1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 21:10:27 +02:00

ELF linker can produce objects with native ABI

* module/system/vm/elf.scm: Define more ABI types and ELF object types.
  Export the ABI, object type, and machine type values.

* module/system/vm/linker.scm (<linker-reloc>, process-reloc): Allow
  rel32/1 relocs.
  (add-elf-objects, allocate-elf, link-elf): Allow the user to set an
  ABI, type, and machine-type.
This commit is contained in:
Andy Wingo 2014-02-16 12:18:44 +01:00
parent a104380d53
commit c90c81898e
2 changed files with 48 additions and 10 deletions

View file

@ -47,6 +47,16 @@
elf-entry elf-phoff elf-shoff elf-flags elf-ehsize elf-entry elf-phoff elf-shoff elf-flags elf-ehsize
elf-phentsize elf-phnum elf-shentsize elf-shnum elf-shstrndx elf-phentsize elf-phnum elf-shentsize elf-shnum elf-shstrndx
ELFOSABI_NONE ELFOSABI_HPUX ELFOSABI_NETBSD ELFOSABI_GNU
ELFOSABI_SOLARIS ELFOSABI_AIX ELFOSABI_IRIX ELFOSABI_FREEBSD
ELFOSABI_TRU64 ELFOSABI_MODESTO ELFOSABI_OPENBSD
ELFOSABI_ARM_AEABI ELFOSABI_ARM ELFOSABI_STANDALONE
ET_NONE ET_REL ET_EXEC ET_DYN ET_CORE
EM_NONE EM_SPARC EM_386 EM_MIPS EM_PPC EM_PPC64 EM_ARM EM_SH
EM_SPARCV9 EM_IA_64 EM_X86_64
elf-header-len elf-header-shoff-offset elf-header-len elf-header-shoff-offset
write-elf-header write-elf-header
@ -169,9 +179,26 @@
(define EV_CURRENT 1) ; Current version (define EV_CURRENT 1) ; Current version
(define ELFOSABI_NONE 0) ; UNIX System V ABI */
(define ELFOSABI_HPUX 1) ; HP-UX
(define ELFOSABI_NETBSD 2) ; NetBSD.
(define ELFOSABI_GNU 3) ; Object uses GNU ELF extensions.
(define ELFOSABI_SOLARIS 6) ; Sun Solaris.
(define ELFOSABI_AIX 7) ; IBM AIX.
(define ELFOSABI_IRIX 8) ; SGI Irix.
(define ELFOSABI_FREEBSD 9) ; FreeBSD.
(define ELFOSABI_TRU64 10) ; Compaq TRU64 UNIX.
(define ELFOSABI_MODESTO 11) ; Novell Modesto.
(define ELFOSABI_OPENBSD 12) ; OpenBSD.
(define ELFOSABI_ARM_AEABI 64) ; ARM EABI
(define ELFOSABI_ARM 97) ; ARM
(define ELFOSABI_STANDALONE 255) ; Standalone (embedded) application (define ELFOSABI_STANDALONE 255) ; Standalone (embedded) application
(define ET_DYN 3) ; Shared object file (define ET_NONE 0) ; No file type
(define ET_REL 1) ; Relocatable file
(define ET_EXEC 2) ; Executable file
(define ET_DYN 3) ; Shared object file
(define ET_CORE 4) ; Core file
;; ;;
;; Machine types ;; Machine types

View file

@ -1,6 +1,6 @@
;;; Guile ELF linker ;;; Guile ELF linker
;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. ;; Copyright (C) 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
;;;; This library is free software; you can redistribute it and/or ;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public ;;;; modify it under the terms of the GNU Lesser General Public
@ -108,13 +108,13 @@
;; to the address. ;; to the address.
;; ;;
;; Two types. Abs32/1 and Abs64/1 are absolute offsets in bytes. ;; Two types. Abs32/1 and Abs64/1 are absolute offsets in bytes.
;; Rel32/4 is a relative signed offset in 32-bit units. Either can have ;; Rel32/1 and Rel32/1 are relative signed offsets, in 8-bit or 32-bit
;; an arbitrary addend as well. ;; units, respectively. Either can have an arbitrary addend as well.
;; ;;
(define-record-type <linker-reloc> (define-record-type <linker-reloc>
(make-linker-reloc type loc addend symbol) (make-linker-reloc type loc addend symbol)
linker-reloc? linker-reloc?
(type linker-reloc-type) ;; rel32/4, abs32/1, abs64/1 (type linker-reloc-type) ;; rel32/1, rel32/4, abs32/1, abs64/1
(loc linker-reloc-loc) (loc linker-reloc-loc)
(addend linker-reloc-addend) (addend linker-reloc-addend)
(symbol linker-reloc-symbol)) (symbol linker-reloc-symbol))
@ -402,6 +402,11 @@ symbol, as present in @var{symtab}."
(bytevector-s32-set! bv offset (bytevector-s32-set! bv offset
(+ (/ diff 4) (linker-reloc-addend reloc)) (+ (/ diff 4) (linker-reloc-addend reloc))
endianness))) endianness)))
((rel32/1)
(let ((diff (- target offset)))
(bytevector-s32-set! bv offset
(+ diff (linker-reloc-addend reloc))
endianness)))
((abs32/1) ((abs32/1)
(bytevector-u32-set! bv offset target endianness)) (bytevector-u32-set! bv offset target endianness))
((abs64/1) ((abs64/1)
@ -447,7 +452,7 @@ section index."
(elf-section-index section)))) (elf-section-index section))))
objects)) objects))
(define (add-elf-objects objects endianness word-size) (define (add-elf-objects objects endianness word-size abi type machine-type)
"Given the list of linker objects supplied by the user, add linker "Given the list of linker objects supplied by the user, add linker
objects corresponding to parts of the ELF file: the null object, the ELF objects corresponding to parts of the ELF file: the null object, the ELF
header, and the section table. header, and the section table.
@ -485,6 +490,7 @@ list of objects, augmented with objects for the special ELF sections."
;; ;;
(define (make-header phnum index shoff-label) (define (make-header phnum index shoff-label)
(let* ((header (make-elf #:byte-order endianness #:word-size word-size (let* ((header (make-elf #:byte-order endianness #:word-size word-size
#:abi abi #:type type #:machine-type machine-type
#:phoff phoff #:phnum phnum #:phentsize phentsize #:phoff phoff #:phnum phnum #:phentsize phentsize
#:shoff 0 #:shnum shnum #:shentsize shentsize #:shoff 0 #:shnum shnum #:shentsize shentsize
#:shstrndx (or (find-shstrndx objects) SHN_UNDEF))) #:shstrndx (or (find-shstrndx objects) SHN_UNDEF)))
@ -574,7 +580,8 @@ list of objects, augmented with objects for the special ELF sections."
(values write-segment-header! objects))) (values write-segment-header! objects)))
(define (allocate-elf objects page-aligned? endianness word-size) (define (allocate-elf objects page-aligned? endianness word-size
abi type machine-type)
"Lay out @var{objects} into an ELF image, computing the size of the "Lay out @var{objects} into an ELF image, computing the size of the
file, the positions of the objects, and the global symbol table. file, the positions of the objects, and the global symbol table.
@ -588,7 +595,7 @@ sections default to 8-byte alignment.
Returns three values: the total image size, a list of objects with Returns three values: the total image size, a list of objects with
relocated headers, and the global symbol table." relocated headers, and the global symbol table."
(receive (write-segment-header! objects) (receive (write-segment-header! objects)
(add-elf-objects objects endianness word-size) (add-elf-objects objects endianness word-size abi type machine-type)
(let lp ((seglists (collate-objects-into-segments objects)) (let lp ((seglists (collate-objects-into-segments objects))
(objects '()) (objects '())
(phidx 0) (phidx 0)
@ -646,7 +653,10 @@ section.)"
(define* (link-elf objects #:key (define* (link-elf objects #:key
(page-aligned? #t) (page-aligned? #t)
(endianness (target-endianness)) (endianness (target-endianness))
(word-size (target-word-size))) (word-size (target-word-size))
(abi ELFOSABI_STANDALONE)
(type ET_DYN)
(machine-type EM_NONE))
"Create an ELF image from the linker objects, @var{objects}. "Create an ELF image from the linker objects, @var{objects}.
If @var{page-aligned?} is true, read-only and writable data are If @var{page-aligned?} is true, read-only and writable data are
@ -659,7 +669,8 @@ alignment.
Returns a bytevector." Returns a bytevector."
(check-section-numbers objects) (check-section-numbers objects)
(receive (size objects symtab) (receive (size objects symtab)
(allocate-elf objects page-aligned? endianness word-size) (allocate-elf objects page-aligned? endianness word-size
abi type machine-type)
(let ((bv (make-bytevector size 0))) (let ((bv (make-bytevector size 0)))
(for-each (for-each
(lambda (object) (lambda (object)