linker.scm 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. ;;; Guile ELF linker
  2. ;; Copyright (C) 2011, 2012, 2013, 2014, 2018 Free Software Foundation, Inc.
  3. ;;;; This library is free software; you can redistribute it and/or
  4. ;;;; modify it under the terms of the GNU Lesser General Public
  5. ;;;; License as published by the Free Software Foundation; either
  6. ;;;; version 3 of the License, or (at your option) any later version.
  7. ;;;;
  8. ;;;; This library is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;;;; Lesser General Public License for more details.
  12. ;;;;
  13. ;;;; You should have received a copy of the GNU Lesser General Public
  14. ;;;; License along with this library; if not, write to the Free Software
  15. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ;;; Commentary:
  17. ;;;
  18. ;;; A linker combines several linker objects into an executable or a
  19. ;;; loadable library.
  20. ;;;
  21. ;;; There are several common formats for libraries out there. Since
  22. ;;; Guile includes its own linker and loader, we are free to choose any
  23. ;;; format, or make up our own.
  24. ;;;
  25. ;;; There are essentially two requirements for a linker format:
  26. ;;; libraries should be able to be loaded with the minimal amount of
  27. ;;; work; and they should support introspection in some way, in order to
  28. ;;; enable good debugging.
  29. ;;;
  30. ;;; These requirements are somewhat at odds, as loading should not have
  31. ;;; to stumble over features related to introspection. It so happens
  32. ;;; that a lot of smart people have thought about this situation, and
  33. ;;; the ELF format embodies the outcome of their thinking. Guile uses
  34. ;;; ELF as its format, regardless of the platform's native library
  35. ;;; format. It's not inconceivable that Guile could interoperate with
  36. ;;; the native dynamic loader at some point, but it's not a near-term
  37. ;;; goal.
  38. ;;;
  39. ;;; Guile's linker takes a list of objects, sorts them according to
  40. ;;; similarity from the perspective of the loader, then writes them out
  41. ;;; into one big bytevector in ELF format.
  42. ;;;
  43. ;;; It is often the case that different parts of a library need to refer
  44. ;;; to each other. For example, program text may need to refer to a
  45. ;;; constant from writable memory. When the linker places sections
  46. ;;; (linker objects) into specific locations in the linked bytevector,
  47. ;;; it needs to fix up those references. This process is called
  48. ;;; /relocation/. References needing relocations are recorded in
  49. ;;; "linker-reloc" objects, and collected in a list in each
  50. ;;; "linker-object". The actual definitions of the references are
  51. ;;; stored in "linker-symbol" objects, also collected in a list in each
  52. ;;; "linker-object".
  53. ;;;
  54. ;;; By default, the ELF files created by the linker include some padding
  55. ;;; so that different parts of the file can be loaded in with different
  56. ;;; permissions. For example, some parts of the file are read-only and
  57. ;;; thus can be shared between processes. Some parts of the file don't
  58. ;;; need to be loaded at all. However this padding can be too much for
  59. ;;; interactive compilation, when the code is never written out to disk;
  60. ;;; in that case, pass #:page-aligned? #f to `link-elf'.
  61. ;;;
  62. ;;; Code:
  63. (define-module (system vm linker)
  64. #:use-module (rnrs bytevectors)
  65. #:use-module (system foreign)
  66. #:use-module (system base target)
  67. #:use-module ((srfi srfi-1) #:select (append-map))
  68. #:use-module (srfi srfi-9)
  69. #:use-module (ice-9 receive)
  70. #:use-module (ice-9 vlist)
  71. #:use-module (ice-9 match)
  72. #:use-module (system vm elf)
  73. #:export (make-linker-reloc
  74. make-linker-symbol
  75. make-linker-object
  76. linker-object?
  77. linker-object-name
  78. linker-object-section
  79. linker-object-bv
  80. linker-object-relocs
  81. (linker-object-symbols* . linker-object-symbols)
  82. make-string-table
  83. string-table-intern!
  84. link-string-table!
  85. link-elf))
  86. (define-syntax fold-values
  87. (lambda (x)
  88. (syntax-case x ()
  89. ((_ proc list seed ...)
  90. (with-syntax (((s ...) (generate-temporaries #'(seed ...))))
  91. #'(let ((p proc))
  92. (let lp ((l list) (s seed) ...)
  93. (match l
  94. (() (values s ...))
  95. ((elt . l)
  96. (call-with-values (lambda () (p elt s ...))
  97. (lambda (s ...) (lp l s ...))))))))))))
  98. ;; A relocation records a reference to a symbol. When the symbol is
  99. ;; resolved to an address, the reloc location will be updated to point
  100. ;; to the address.
  101. ;;
  102. ;; Two types. Abs32/1 and Abs64/1 are absolute offsets in bytes.
  103. ;; Rel32/1 and Rel32/1 are relative signed offsets, in 8-bit or 32-bit
  104. ;; units, respectively. Either can have an arbitrary addend as well.
  105. ;;
  106. (define-record-type <linker-reloc>
  107. (make-linker-reloc type loc addend symbol)
  108. linker-reloc?
  109. (type linker-reloc-type) ;; rel32/1, rel32/4, abs32/1, abs64/1
  110. (loc linker-reloc-loc)
  111. (addend linker-reloc-addend)
  112. (symbol linker-reloc-symbol))
  113. ;; A symbol is an association between a name and an address. The
  114. ;; address is always in regard to some particular address space. When
  115. ;; objects come into the linker, their symbols live in the object
  116. ;; address space. When the objects are allocated into ELF segments, the
  117. ;; symbols will be relocated into memory address space, corresponding to
  118. ;; the position the ELF will be loaded at.
  119. ;;
  120. (define-record-type <linker-symbol>
  121. (make-linker-symbol name address)
  122. linker-symbol?
  123. (name linker-symbol-name)
  124. (address linker-symbol-address))
  125. (define-record-type <linker-object>
  126. (%make-linker-object name section bv relocs symbols)
  127. linker-object?
  128. (name linker-object-name)
  129. (section linker-object-section)
  130. (bv linker-object-bv)
  131. (relocs linker-object-relocs)
  132. (symbols linker-object-symbols))
  133. (define (make-linker-object name section bv relocs symbols)
  134. "Create a linker object named @var{name} (a string, or #f for no name),
  135. @code{<elf-section>} header @var{section}, bytevector contents @var{bv},
  136. list of linker relocations @var{relocs}, and list of linker symbols
  137. @var{symbols}."
  138. (%make-linker-object name section bv relocs
  139. ;; Hide a symbol to the beginning of the section
  140. ;; in the symbols.
  141. (cons (make-linker-symbol (gensym "*section*") 0)
  142. symbols)))
  143. (define (linker-object-section-symbol object)
  144. "Return the linker symbol corresponding to the start of this section."
  145. (car (linker-object-symbols object)))
  146. (define (linker-object-symbols* object)
  147. "Return the linker symbols defined by the user for this this section."
  148. (cdr (linker-object-symbols object)))
  149. (define-record-type <string-table>
  150. (%make-string-table strings linked?)
  151. string-table?
  152. (strings string-table-strings set-string-table-strings!)
  153. (linked? string-table-linked? set-string-table-linked?!))
  154. (define (make-string-table)
  155. "Return a string table with one entry: the empty string."
  156. (%make-string-table '(("" 0 #vu8())) #f))
  157. (define (string-table-length strings)
  158. "Return the number of bytes needed for the @var{strings}."
  159. (match strings
  160. (((str pos bytes) . _)
  161. ;; The + 1 is for the trailing NUL byte.
  162. (+ pos (bytevector-length bytes) 1))))
  163. (define (string-table-intern! table str)
  164. "Ensure that @var{str} is present in the string table @var{table}.
  165. Returns the byte index of the string in that table."
  166. (match table
  167. (($ <string-table> strings linked?)
  168. (match (assoc str strings)
  169. ((_ pos _) pos)
  170. (#f
  171. (let ((next (string-table-length strings)))
  172. (when linked?
  173. (error "string table already linked, can't intern" table str))
  174. (set-string-table-strings! table
  175. (cons (list str next (string->utf8 str))
  176. strings))
  177. next))))))
  178. (define (link-string-table! table)
  179. "Link the functional string table @var{table} into a sequence of
  180. bytes, suitable for use as the contents of an ELF string table section."
  181. (match table
  182. (($ <string-table> strings #f)
  183. (let ((out (make-bytevector (string-table-length strings) 0)))
  184. (for-each
  185. (match-lambda
  186. ((_ pos bytes)
  187. (bytevector-copy! bytes 0 out pos (bytevector-length bytes))))
  188. strings)
  189. (set-string-table-linked?! table #t)
  190. out))))
  191. (define (segment-kind section)
  192. "Return the type of segment needed to store @var{section}, as a pair.
  193. The car is the @code{PT_} segment type, or @code{#f} if the section
  194. doesn't need to be present in a loadable segment. The cdr is a bitfield
  195. of associated @code{PF_} permissions."
  196. (let ((flags (elf-section-flags section)))
  197. ;; Sections without SHF_ALLOC don't go in segments.
  198. (cons (if (zero? flags) #f PT_LOAD)
  199. (logior (if (logtest SHF_ALLOC flags) PF_R 0)
  200. (if (logtest SHF_EXECINSTR flags) PF_X 0)
  201. (if (logtest SHF_WRITE flags) PF_W 0)))))
  202. (define (count-segments objects)
  203. "Return the total number of segments needed to represent the linker
  204. objects in @var{objects}, including the segment needed for the ELF
  205. header and segment table."
  206. (define (adjoin x xs)
  207. (if (member x xs) xs (cons x xs)))
  208. (length
  209. (fold-values (lambda (object kinds)
  210. (let ((kind (segment-kind (linker-object-section object))))
  211. (if (= (elf-section-type (linker-object-section object))
  212. SHT_DYNAMIC)
  213. ;; The dynamic section is part of a loadable
  214. ;; segment, and also gets the additional
  215. ;; PT_DYNAMIC segment header.
  216. (cons (cons PT_DYNAMIC (cdr kind))
  217. (adjoin kind kinds))
  218. (if (car kind) (adjoin kind kinds) kinds))))
  219. objects
  220. ;; We know there will be at least one segment,
  221. ;; containing at least the header and segment table.
  222. (list (cons PT_LOAD PF_R)))))
  223. (define (group-by-cars ls)
  224. (let lp ((ls ls) (k #f) (group #f) (out '()))
  225. (match ls
  226. (()
  227. (reverse!
  228. (if group
  229. (cons (cons k (reverse! group)) out)
  230. out)))
  231. (((k* . v) . ls)
  232. (if (and group (equal? k k*))
  233. (lp ls k (cons v group) out)
  234. (lp ls k* (list v)
  235. (if group
  236. (cons (cons k (reverse! group)) out)
  237. out)))))))
  238. (define (collate-objects-into-segments objects)
  239. "Given the list of linker objects @var{objects}, group them into
  240. contiguous ELF segments of the same type and flags. The result is an
  241. alist that maps segment types to lists of linker objects. See
  242. @code{segment-type} for a description of segment types. Within a
  243. segment, the order of the linker objects is preserved."
  244. (group-by-cars
  245. (stable-sort!
  246. (map (lambda (o)
  247. (cons (segment-kind (linker-object-section o)) o))
  248. objects)
  249. (lambda (x y)
  250. (let* ((x-kind (car x)) (y-kind (car y))
  251. (x-type (car x-kind)) (y-type (car y-kind))
  252. (x-flags (cdr x-kind)) (y-flags (cdr y-kind))
  253. (x-section (linker-object-section (cdr x)))
  254. (y-section (linker-object-section (cdr y))))
  255. (cond
  256. ((not (equal? x-kind y-kind))
  257. (cond
  258. ((and x-type y-type)
  259. (cond
  260. ((not (equal? x-flags y-flags))
  261. (< x-flags y-flags))
  262. (else
  263. (< x-type y-type))))
  264. (else
  265. (not y-type))))
  266. ((not (equal? (elf-section-type x-section)
  267. (elf-section-type y-section)))
  268. (cond
  269. ((equal? (elf-section-type x-section) SHT_NOBITS) #t)
  270. ((equal? (elf-section-type y-section) SHT_NOBITS) #f)
  271. (else (< (elf-section-type x-section)
  272. (elf-section-type y-section)))))
  273. (else
  274. ;; Leave them in the initial order. This allows us to ensure
  275. ;; that the ELF header is written first.
  276. #f)))))))
  277. (define (align address alignment)
  278. (if (zero? alignment)
  279. address
  280. (+ address
  281. (modulo (- alignment (modulo address alignment)) alignment))))
  282. (define (relocate-section-header sec offset)
  283. "Return a new section header, just like @var{sec} but with its
  284. @code{offset} (and @code{addr} if it is loadable) set to @var{offset}."
  285. (make-elf-section #:index (elf-section-index sec)
  286. #:name (elf-section-name sec)
  287. #:type (elf-section-type sec)
  288. #:flags (elf-section-flags sec)
  289. #:addr (if (zero? (logand SHF_ALLOC
  290. (elf-section-flags sec)))
  291. 0
  292. offset)
  293. #:offset offset
  294. #:size (elf-section-size sec)
  295. #:link (elf-section-link sec)
  296. #:info (elf-section-info sec)
  297. #:addralign (elf-section-addralign sec)
  298. #:entsize (elf-section-entsize sec)))
  299. ;; We assume that 64K is a multiple of the page size. A
  300. ;; least-common-multiple, if you will.
  301. ;;
  302. ;; It would be possible to choose smaller, target-specific page sizes.
  303. ;; This is still a little tricky; on amd64 for example, systems commonly
  304. ;; have 4KB pages, but they are allowed by the ABI to have any
  305. ;; multiple-of-2 page size up to 64 KB. On Cygwin, pages are 4kB but
  306. ;; they can only be allocated 16 at a time. MIPS and ARM64 can use 64K
  307. ;; pages too and that's not uncommon.
  308. ;;
  309. ;; At the current time, in Guile we would like to reduce the number of
  310. ;; binaries we ship to the existing 32-or-64-bit and
  311. ;; big-or-little-endian variants, if possible. It would seem that with
  312. ;; the least-common-multiple of 64 KB pages, we can do that.
  313. ;;
  314. ;; See https://github.com/golang/go/issues/10180 for a discussion of
  315. ;; this issue in the Go context.
  316. ;;
  317. ;; Using 64KB instead of the more usual 4KB will increase the size of
  318. ;; our .go files, but not the prebuilt/ part of the tarball as that part
  319. ;; of the file will be zeroes and compress well. Additionally on a
  320. ;; system with 4KB pages, the extra padding will never be paged in, nor
  321. ;; read from disk (though it causes more seeking etc so on spinning
  322. ;; metal it's a bit of a lose).
  323. ;;
  324. ;; By way of comparison, on many 64-bit platforms, binutils currently
  325. ;; defaults to aligning segments on 2MB boundaries. It does so by
  326. ;; making the file and the memory images not the same: the pages are all
  327. ;; together on disk, but then when loading, the loader will mmap a
  328. ;; region "memsz" large which might be greater than the file size, then
  329. ;; map segments into that region. We can avoid this complication for
  330. ;; now. We can consider adding it in the future in a compatible way in
  331. ;; 2.2 if it is important.
  332. ;;
  333. (define *lcm-page-size* (ash 1 16))
  334. (define (add-symbols symbols offset symtab)
  335. "Add @var{symbols} to the symbol table @var{symtab}, relocating them
  336. from object address space to memory address space. Returns a new symbol
  337. table."
  338. (fold-values
  339. (lambda (symbol symtab)
  340. (let ((name (linker-symbol-name symbol))
  341. (addr (linker-symbol-address symbol)))
  342. (when (vhash-assq name symtab)
  343. (error "duplicate symbol" name))
  344. (vhash-consq name (make-linker-symbol name (+ addr offset)) symtab)))
  345. symbols
  346. symtab))
  347. (define (allocate-segment write-segment-header!
  348. phidx type flags objects addr symtab alignment)
  349. "Given a list of linker objects that should go in a segment, the type
  350. and flags that the segment should have, and the address at which the
  351. segment should start, compute the positions that each object should have
  352. in the segment.
  353. Returns three values: the address of the next byte after the segment, a
  354. list of relocated objects, and the symbol table. The symbol table is
  355. the same as @var{symtab}, augmented with the symbols defined in
  356. @var{objects}, relocated to their positions in the image.
  357. In what is something of a quirky interface, this routine also patches up
  358. the segment table using @code{write-segment-header!}."
  359. (let* ((alignment (fold-values (lambda (o alignment)
  360. (lcm (elf-section-addralign
  361. (linker-object-section o))
  362. alignment))
  363. objects
  364. alignment))
  365. (addr (align addr alignment)))
  366. (receive (objects endaddr symtab)
  367. (fold-values
  368. (lambda (o out addr symtab)
  369. (let* ((section (linker-object-section o))
  370. (addr (align addr (elf-section-addralign section))))
  371. (values
  372. (cons (make-linker-object
  373. (linker-object-name o)
  374. (relocate-section-header section addr)
  375. (linker-object-bv o)
  376. (linker-object-relocs o)
  377. (linker-object-symbols o))
  378. out)
  379. (+ addr (elf-section-size section))
  380. (add-symbols (linker-object-symbols o) addr symtab))))
  381. objects
  382. '() addr symtab)
  383. (when type
  384. (write-segment-header!
  385. (make-elf-segment #:index phidx #:type type
  386. #:offset addr #:vaddr addr #:paddr addr
  387. #:filesz (- endaddr addr) #:memsz (- endaddr addr)
  388. #:flags flags #:align alignment)))
  389. (values endaddr
  390. (reverse objects)
  391. symtab))))
  392. (define (process-reloc reloc bv section-offset symtab endianness)
  393. "Process a relocation. Given that a section containing @var{reloc}
  394. was just written into the image @var{bv} at offset @var{section-offset},
  395. fix it up so that its reference points to the correct position of its
  396. symbol, as present in @var{symtab}."
  397. (match (vhash-assq (linker-reloc-symbol reloc) symtab)
  398. (#f
  399. (error "Undefined symbol" (linker-reloc-symbol reloc)))
  400. ((name . symbol)
  401. ;; The reloc was written at LOC bytes after SECTION-OFFSET.
  402. (let* ((offset (+ (linker-reloc-loc reloc) section-offset))
  403. (target (linker-symbol-address symbol)))
  404. (case (linker-reloc-type reloc)
  405. ((rel32/4)
  406. (let ((diff (+ (- target offset) (linker-reloc-addend reloc))))
  407. (unless (zero? (modulo diff 4))
  408. (error "Bad offset" reloc symbol offset))
  409. (bytevector-s32-set! bv offset (/ diff 4) endianness)))
  410. ((rel32/1)
  411. (let ((diff (- target offset)))
  412. (bytevector-s32-set! bv offset
  413. (+ diff (linker-reloc-addend reloc))
  414. endianness)))
  415. ((abs32/1)
  416. (bytevector-u32-set! bv offset target endianness))
  417. ((abs64/1)
  418. (bytevector-u64-set! bv offset target endianness))
  419. (else
  420. (error "bad reloc type" reloc)))))))
  421. (define (write-linker-object bv o symtab endianness)
  422. "Write the bytevector for the section wrapped by the linker object
  423. @var{o} into the image @var{bv}. The section header in @var{o} should
  424. already be relocated its final position in the image. Any relocations
  425. in the section will be processed to point to the correct symbol
  426. locations, as given in @var{symtab}."
  427. (let* ((section (linker-object-section o))
  428. (offset (elf-section-offset section))
  429. (len (elf-section-size section))
  430. (bytes (linker-object-bv o))
  431. (relocs (linker-object-relocs o)))
  432. (if (zero? (logand SHF_ALLOC (elf-section-flags section)))
  433. (unless (zero? (elf-section-addr section))
  434. (error "non-loadable section has non-zero addr" section))
  435. (unless (= offset (elf-section-addr section))
  436. (error "loadable section has offset != addr" section)))
  437. (if (not (= (elf-section-type section) SHT_NOBITS))
  438. (begin
  439. (if (not (= len (bytevector-length bytes)))
  440. (error "unexpected length" section bytes))
  441. (bytevector-copy! bytes 0 bv offset len)
  442. (for-each (lambda (reloc)
  443. (process-reloc reloc bv offset symtab endianness))
  444. relocs)))))
  445. (define (find-shstrndx objects)
  446. "Find the section name string table in @var{objects}, and return its
  447. section index."
  448. (or-map (lambda (object)
  449. (and (equal? (linker-object-name object) ".shstrtab")
  450. (elf-section-index (linker-object-section object))))
  451. objects))
  452. (define (add-elf-objects objects endianness word-size abi type machine-type)
  453. "Given the list of linker objects supplied by the user, add linker
  454. objects corresponding to parts of the ELF file: the null object, the ELF
  455. header, and the section table.
  456. Both of these internal objects include relocs, allowing their
  457. inter-object references to be patched up when the final image allocation
  458. is known. There is special support for patching up the segment table,
  459. however. Because the segment table needs to know the segment sizes,
  460. which is the difference between two symbols in image space, and there is
  461. no reloc kind that is the difference between two symbols, we make a hack
  462. and return a closure that patches up segment table entries. It seems to
  463. work.
  464. Returns two values: the procedure to patch the segment table, and the
  465. list of objects, augmented with objects for the special ELF sections."
  466. (define phoff (elf-header-len word-size))
  467. (define phentsize (elf-program-header-len word-size))
  468. (define shentsize (elf-section-header-len word-size))
  469. (define shnum (+ (length objects) 3))
  470. (define reloc-kind
  471. (case word-size
  472. ((4) 'abs32/1)
  473. ((8) 'abs64/1)
  474. (else (error "bad word size" word-size))))
  475. ;; ELF requires that the first entry in the section table be of type
  476. ;; SHT_NULL.
  477. ;;
  478. (define (make-null-section)
  479. (make-linker-object ""
  480. (make-elf-section #:index 0 #:type SHT_NULL
  481. #:flags 0 #:addralign 0)
  482. #vu8() '() '()))
  483. ;; The ELF header and the segment table.
  484. ;;
  485. (define (make-header phnum index shoff-label)
  486. (let* ((header (make-elf #:byte-order endianness #:word-size word-size
  487. #:abi abi #:type type #:machine-type machine-type
  488. #:phoff phoff #:phnum phnum #:phentsize phentsize
  489. #:shoff 0 #:shnum shnum #:shentsize shentsize
  490. #:shstrndx (or (find-shstrndx objects) SHN_UNDEF)))
  491. (shoff-reloc (make-linker-reloc reloc-kind
  492. (elf-header-shoff-offset word-size)
  493. 0
  494. shoff-label))
  495. (size (+ phoff (* phnum phentsize)))
  496. (bv (make-bytevector size 0)))
  497. (write-elf-header bv header)
  498. ;; Leave the segment table uninitialized; it will be filled in
  499. ;; later by calls to the write-segment-header! closure.
  500. (make-linker-object #f
  501. (make-elf-section #:index index #:type SHT_PROGBITS
  502. #:flags SHF_ALLOC #:size size)
  503. bv
  504. (list shoff-reloc)
  505. '())))
  506. ;; The section table.
  507. ;;
  508. (define (make-footer objects shoff-label)
  509. (let* ((size (* shentsize shnum))
  510. (bv (make-bytevector size 0))
  511. (section-table (make-elf-section #:index (length objects)
  512. #:type SHT_PROGBITS
  513. #:flags 0
  514. #:size size)))
  515. (define (write-and-reloc section-label section relocs)
  516. (let ((offset (* shentsize (elf-section-index section))))
  517. (write-elf-section-header bv offset endianness word-size section)
  518. (if (= (elf-section-type section) SHT_NULL)
  519. relocs
  520. (let ((relocs
  521. (cons (make-linker-reloc
  522. reloc-kind
  523. (+ offset
  524. (elf-section-header-offset-offset word-size))
  525. 0
  526. section-label)
  527. relocs)))
  528. (if (zero? (logand SHF_ALLOC (elf-section-flags section)))
  529. relocs
  530. (cons (make-linker-reloc
  531. reloc-kind
  532. (+ offset
  533. (elf-section-header-addr-offset word-size))
  534. 0
  535. section-label)
  536. relocs))))))
  537. (let ((relocs (fold-values
  538. (lambda (object relocs)
  539. (write-and-reloc
  540. (linker-symbol-name
  541. (linker-object-section-symbol object))
  542. (linker-object-section object)
  543. relocs))
  544. objects
  545. (write-and-reloc shoff-label section-table '()))))
  546. (%make-linker-object #f section-table bv relocs
  547. (list (make-linker-symbol shoff-label 0))))))
  548. (let* ((null-section (make-null-section))
  549. (objects (cons null-section objects))
  550. (shoff (gensym "*section-table*"))
  551. (header (make-header (count-segments objects) (length objects) shoff))
  552. (objects (cons header objects))
  553. (footer (make-footer objects shoff))
  554. (objects (cons footer objects)))
  555. ;; The header includes the segment table, which needs offsets and
  556. ;; sizes of the segments. Normally we would use relocs to rewrite
  557. ;; these values, but there is no reloc type that would allow us to
  558. ;; compute size. Such a reloc would need to take the difference
  559. ;; between two symbols, and it's probably a bad idea architecturally
  560. ;; to create one.
  561. ;;
  562. ;; So instead we return a closure to patch up the segment table.
  563. ;; Normally we'd shy away from such destructive interfaces, but it's
  564. ;; OK as we create the header section ourselves.
  565. ;;
  566. (define (write-segment-header! segment)
  567. (let ((bv (linker-object-bv header))
  568. (offset (+ phoff (* (elf-segment-index segment) phentsize))))
  569. (write-elf-program-header bv offset endianness word-size segment)))
  570. (values write-segment-header! objects)))
  571. (define (record-special-segments write-segment-header! phidx all-objects)
  572. (let lp ((phidx phidx) (objects all-objects))
  573. (match objects
  574. (() #t)
  575. ((object . objects)
  576. (let ((section (linker-object-section object)))
  577. (cond
  578. ((eqv? (elf-section-type section) SHT_DYNAMIC)
  579. (let ((addr (elf-section-offset section))
  580. (size (elf-section-size section))
  581. (align (elf-section-addralign section))
  582. (flags (cdr (segment-kind section))))
  583. (write-segment-header!
  584. (make-elf-segment #:index phidx #:type PT_DYNAMIC
  585. #:offset addr #:vaddr addr #:paddr addr
  586. #:filesz size #:memsz size
  587. #:flags flags #:align align))
  588. (lp (1+ phidx) objects)))
  589. (else
  590. (lp phidx objects))))))))
  591. (define (allocate-elf objects page-aligned? endianness word-size
  592. abi type machine-type)
  593. "Lay out @var{objects} into an ELF image, computing the size of the
  594. file, the positions of the objects, and the global symbol table.
  595. If @var{page-aligned?} is true, read-only and writable data are
  596. separated so that only those writable parts of the image need be mapped
  597. with writable permissions. This makes the resulting image larger. It
  598. is more suitable to situations where you would write a file out to disk
  599. and read it in with mmap. Otherwise if @var{page-aligned?} is false,
  600. sections default to 8-byte alignment.
  601. Returns three values: the total image size, a list of objects with
  602. relocated headers, and the global symbol table."
  603. (receive (write-segment-header! objects)
  604. (add-elf-objects objects endianness word-size abi type machine-type)
  605. (let lp ((seglists (collate-objects-into-segments objects))
  606. (objects '())
  607. (phidx 0)
  608. (addr 0)
  609. (symtab vlist-null)
  610. (prev-flags 0))
  611. (match seglists
  612. ((((type . flags) objs-in ...) seglists ...)
  613. (receive (addr objs-out symtab)
  614. (allocate-segment
  615. write-segment-header!
  616. phidx type flags objs-in addr symtab
  617. (if (and page-aligned?
  618. (not (= flags prev-flags))
  619. ;; Allow sections that are not in
  620. ;; loadable segments to share pages
  621. ;; with PF_R segments.
  622. (not (and (not type) (= PF_R prev-flags))))
  623. *lcm-page-size*
  624. 8))
  625. (lp seglists
  626. (fold-values cons objs-out objects)
  627. (if type (1+ phidx) phidx)
  628. addr
  629. symtab
  630. flags)))
  631. (()
  632. (record-special-segments write-segment-header! phidx objects)
  633. (values addr
  634. (reverse objects)
  635. symtab))))))
  636. (define (check-section-numbers objects)
  637. "Verify that taken as a whole, that all objects have distinct,
  638. contiguous section numbers, starting from 1. (Section 0 is the null
  639. section.)"
  640. (let* ((nsections (1+ (length objects))) ; 1+ for initial NULL section.
  641. (sections (make-vector nsections #f)))
  642. (for-each (lambda (object)
  643. (let ((n (elf-section-index (linker-object-section object))))
  644. (cond
  645. ((< n 1)
  646. (error "Invalid section number" object))
  647. ((>= n nsections)
  648. (error "Invalid section number" object))
  649. ((vector-ref sections n)
  650. (error "Duplicate section" (vector-ref sections n) object))
  651. (else
  652. (vector-set! sections n object)))))
  653. objects)))
  654. ;; Given a list of linker objects, collate the objects into segments,
  655. ;; allocate the segments, allocate the ELF bytevector, and write the
  656. ;; segments into the bytevector, relocating as we go.
  657. ;;
  658. (define* (link-elf objects #:key
  659. (page-aligned? #t)
  660. (endianness (target-endianness))
  661. (word-size (target-word-size))
  662. (abi ELFOSABI_STANDALONE)
  663. (type ET_DYN)
  664. (machine-type EM_NONE))
  665. "Create an ELF image from the linker objects, @var{objects}.
  666. If @var{page-aligned?} is true, read-only and writable data are
  667. separated so that only those writable parts of the image need be mapped
  668. with writable permissions. This is suitable for situations where you
  669. would write a file out to disk and read it in with @code{mmap}.
  670. Otherwise if @var{page-aligned?} is false, sections default to 8-byte
  671. alignment.
  672. Returns a bytevector."
  673. (check-section-numbers objects)
  674. (receive (size objects symtab)
  675. (allocate-elf objects page-aligned? endianness word-size
  676. abi type machine-type)
  677. (let ((bv (make-bytevector size 0)))
  678. (for-each
  679. (lambda (object)
  680. (write-linker-object bv object symtab endianness))
  681. objects)
  682. bv)))