1 /* SPDX-License-Identifier: GPL-2.0-only */
8 #include "elfparsing.h"
10 #include <commonlib/rmodule-defs.h>
13 * Architecture specific support operations.
15 static int valid_reloc_386(Elf64_Rela
*rel
)
19 type
= ELF64_R_TYPE(rel
->r_info
);
21 /* Only these 2 relocations are expected to be found. */
22 return (type
== R_386_32
|| type
== R_386_PC32
);
25 static int should_emit_386(Elf64_Rela
*rel
)
29 type
= ELF64_R_TYPE(rel
->r_info
);
31 /* R_386_32 relocations are absolute. Must emit these. */
32 return (type
== R_386_32
);
35 static int valid_reloc_amd64(Elf64_Rela
*rel
)
39 type
= ELF64_R_TYPE(rel
->r_info
);
41 /* Only these 6 relocations are expected to be found. */
42 return (type
== R_AMD64_64
||
43 type
== R_AMD64_PC64
||
44 type
== R_AMD64_32S
||
46 type
== R_AMD64_PC32
||
48 * binutils 2.31 introduced R_AMD64_PLT32 for non local
49 * functions. As we don't care about procedure linkage
50 * table entries handle it as R_X86_64_PC32.
52 type
== R_AMD64_PLT32
);
55 static int should_emit_amd64(Elf64_Rela
*rel
)
59 type
= ELF64_R_TYPE(rel
->r_info
);
61 /* Only emit absolute relocations */
62 return (type
== R_AMD64_64
||
63 type
== R_AMD64_32S
||
67 static int valid_reloc_arm(Elf64_Rela
*rel
)
71 type
= ELF64_R_TYPE(rel
->r_info
);
73 /* Only these 6 relocations are expected to be found. */
74 return (type
== R_ARM_ABS32
|| type
== R_ARM_THM_PC22
||
75 type
== R_ARM_THM_JUMP24
|| type
== R_ARM_V4BX
||
76 type
== R_ARM_CALL
|| type
== R_ARM_JUMP24
);
79 static int should_emit_arm(Elf64_Rela
*rel
)
83 type
= ELF64_R_TYPE(rel
->r_info
);
85 /* R_ARM_ABS32 relocations are absolute. Must emit these. */
86 return (type
== R_ARM_ABS32
);
89 static int valid_reloc_aarch64(Elf64_Rela
*rel
)
93 type
= ELF64_R_TYPE(rel
->r_info
);
95 return (type
== R_AARCH64_ADR_PREL_PG_HI21
||
96 type
== R_AARCH64_ADD_ABS_LO12_NC
||
97 type
== R_AARCH64_LDST8_ABS_LO12_NC
||
98 type
== R_AARCH64_CONDBR19
||
99 type
== R_AARCH64_JUMP26
||
100 type
== R_AARCH64_LDST32_ABS_LO12_NC
||
101 type
== R_AARCH64_LDST64_ABS_LO12_NC
||
102 type
== R_AARCH64_CALL26
||
103 type
== R_AARCH64_ABS64
||
104 type
== R_AARCH64_LD_PREL_LO19
||
105 type
== R_AARCH64_ADR_PREL_LO21
);
108 static int should_emit_aarch64(Elf64_Rela
*rel
)
112 type
= ELF64_R_TYPE(rel
->r_info
);
114 return (type
== R_AARCH64_ABS64
);
117 static const struct arch_ops reloc_ops
[] = {
120 .valid_type
= valid_reloc_386
,
121 .should_emit
= should_emit_386
,
125 .valid_type
= valid_reloc_amd64
,
126 .should_emit
= should_emit_amd64
,
130 .valid_type
= valid_reloc_arm
,
131 .should_emit
= should_emit_arm
,
135 .valid_type
= valid_reloc_aarch64
,
136 .should_emit
= should_emit_aarch64
,
141 * Relocation processing loops.
144 static int for_each_reloc(struct rmod_context
*ctx
, struct reloc_filter
*f
,
148 struct parsed_elf
*pelf
= &ctx
->pelf
;
150 for (i
= 0; i
< pelf
->ehdr
.e_shnum
; i
++) {
156 relocs
= pelf
->relocs
[i
];
158 /* No relocations in this section. */
162 shdr
= &pelf
->shdr
[i
];
163 nrelocs
= shdr
->sh_size
/ shdr
->sh_entsize
;
165 for (j
= 0; j
< nrelocs
; j
++) {
167 Elf64_Rela
*r
= &relocs
[j
];
169 if (!ctx
->ops
->valid_type(r
)) {
170 ERROR("Invalid reloc type: %u\n",
171 (unsigned int)ELF64_R_TYPE(r
->r_info
));
175 /* Allow the provided filter to have precedence. */
177 filter_emit
= f
->filter(f
, r
);
183 if (filter_emit
&& ctx
->ops
->should_emit(r
)) {
184 int n
= ctx
->nrelocs
;
186 ctx
->emitted_relocs
[n
] = r
->r_offset
;
195 static int find_program_segment(struct rmod_context
*ctx
)
199 struct parsed_elf
*pelf
;
200 Elf64_Phdr
*phdr
= NULL
;
204 /* There should only be a single loadable segment. */
206 for (i
= 0; i
< pelf
->ehdr
.e_phnum
; i
++) {
207 if (pelf
->phdr
[i
].p_type
!= PT_LOAD
)
209 phdr
= &pelf
->phdr
[i
];
213 if (nsegments
!= 1) {
214 ERROR("Unexpected number of loadable segments: %d.\n",
219 INFO("Segment at 0x%0llx, file size 0x%0llx, mem size 0x%0llx.\n",
220 (long long)phdr
->p_vaddr
, (long long)phdr
->p_filesz
,
221 (long long)phdr
->p_memsz
);
229 filter_relocation_sections(struct rmod_context
*ctx
)
232 const char *shstrtab
;
233 struct parsed_elf
*pelf
;
234 const Elf64_Phdr
*phdr
;
238 shstrtab
= buffer_get(pelf
->strtabs
[pelf
->ehdr
.e_shstrndx
]);
241 * Find all relocation sections that contain relocation entries
242 * for sections that fall within the bounds of the segment. For
243 * easier processing the pointer to the relocation array for the
244 * sections that don't fall within the loadable program are NULL'd
247 for (i
= 0; i
< pelf
->ehdr
.e_shnum
; i
++) {
250 const char *section_name
;
252 shdr
= &pelf
->shdr
[i
];
254 /* Ignore non-relocation sections. */
255 if (shdr
->sh_type
!= SHT_RELA
&& shdr
->sh_type
!= SHT_REL
)
258 /* Obtain section which relocations apply. */
259 sh_info
= shdr
->sh_info
;
260 shdr
= &pelf
->shdr
[sh_info
];
262 section_name
= &shstrtab
[shdr
->sh_name
];
263 DEBUG("Relocation section found for '%s' section.\n",
266 /* Do not process relocations for debug sections. */
267 if (strstr(section_name
, ".debug") != NULL
) {
268 pelf
->relocs
[i
] = NULL
;
273 * If relocations apply to a non program section ignore the
274 * relocations for future processing.
276 if (shdr
->sh_type
!= SHT_PROGBITS
) {
277 pelf
->relocs
[i
] = NULL
;
281 if (shdr
->sh_addr
< phdr
->p_vaddr
||
282 ((shdr
->sh_addr
+ shdr
->sh_size
) >
283 (phdr
->p_vaddr
+ phdr
->p_memsz
))) {
284 ERROR("Relocations being applied to section %d not "
285 "within segment region.\n", sh_info
);
293 static int vaddr_cmp(const void *a
, const void *b
)
295 const Elf64_Addr
*pa
= a
;
296 const Elf64_Addr
*pb
= b
;
305 int rmodule_collect_relocations(struct rmod_context
*ctx
,
306 struct reloc_filter
*f
)
311 * The relocs array in the pelf should only contain relocations that
312 * apply to the program. Count the number relocations. Then collect
313 * them into the allocated buffer.
315 if (for_each_reloc(ctx
, f
, 0))
318 nrelocs
= ctx
->nrelocs
;
319 INFO("%" PRIu64
" relocations to be emitted.\n", nrelocs
);
323 /* Reset the counter for indexing into the array. */
325 ctx
->emitted_relocs
= calloc(nrelocs
, sizeof(Elf64_Addr
));
326 /* Write out the relocations into the emitted_relocs array. */
327 if (for_each_reloc(ctx
, f
, 1))
330 if (ctx
->nrelocs
!= nrelocs
) {
331 ERROR("Mismatch counted and emitted relocations: %zu vs %zu.\n",
332 (size_t)nrelocs
, (size_t)ctx
->nrelocs
);
336 /* Sort the relocations by their address. */
337 qsort(ctx
->emitted_relocs
, nrelocs
, sizeof(Elf64_Addr
), vaddr_cmp
);
343 populate_sym(struct rmod_context
*ctx
, const char *sym_name
, Elf64_Addr
*addr
,
344 int nsyms
, const char *strtab
, int optional
)
349 syms
= ctx
->pelf
.syms
;
351 for (i
= 0; i
< nsyms
; i
++) {
352 if (syms
[i
].st_name
== 0)
354 if (strcmp(sym_name
, &strtab
[syms
[i
].st_name
]))
356 DEBUG("%s -> 0x%llx\n", sym_name
, (long long)syms
[i
].st_value
);
357 *addr
= syms
[i
].st_value
;
362 DEBUG("optional symbol '%s' not found.\n", sym_name
);
367 ERROR("symbol '%s' not found.\n", sym_name
);
371 static int populate_rmodule_info(struct rmod_context
*ctx
)
375 struct parsed_elf
*pelf
;
382 /* Obtain the string table. */
384 for (i
= 0; i
< ehdr
->e_shnum
; i
++) {
385 if (ctx
->pelf
.strtabs
[i
] == NULL
)
387 /* Don't use the section headers' string table. */
388 if (i
== ehdr
->e_shstrndx
)
390 strtab
= buffer_get(ctx
->pelf
.strtabs
[i
]);
394 if (strtab
== NULL
) {
395 ERROR("No string table found.\n");
399 /* Determine number of symbols. */
401 for (i
= 0; i
< ehdr
->e_shnum
; i
++) {
402 if (pelf
->shdr
[i
].sh_type
!= SHT_SYMTAB
)
405 nsyms
= pelf
->shdr
[i
].sh_size
/ pelf
->shdr
[i
].sh_entsize
;
409 if (populate_sym(ctx
, "_rmodule_params", &ctx
->parameters_begin
,
413 if (populate_sym(ctx
, "_ermodule_params", &ctx
->parameters_end
,
417 if (populate_sym(ctx
, "_bss", &ctx
->bss_begin
, nsyms
, strtab
, 0))
420 if (populate_sym(ctx
, "_ebss", &ctx
->bss_end
, nsyms
, strtab
, 0))
427 add_section(struct elf_writer
*ew
, struct buffer
*data
, const char *name
,
428 Elf64_Addr addr
, Elf64_Word size
)
433 memset(&shdr
, 0, sizeof(shdr
));
435 shdr
.sh_type
= SHT_PROGBITS
;
436 shdr
.sh_flags
= SHF_ALLOC
| SHF_WRITE
| SHF_EXECINSTR
;
438 shdr
.sh_type
= SHT_NOBITS
;
439 shdr
.sh_flags
= SHF_ALLOC
;
442 shdr
.sh_offset
= addr
;
445 ret
= elf_writer_add_section(ew
, &shdr
, data
, name
);
448 ERROR("Could not add '%s' section.\n", name
);
454 write_elf(const struct rmod_context
*ctx
, const struct buffer
*in
,
460 size_t rmod_data_size
;
461 struct elf_writer
*ew
;
462 struct buffer rmod_data
;
463 struct buffer rmod_header
;
464 struct buffer program
;
465 struct buffer relocs
;
466 Elf64_Xword total_size
;
470 bit64
= ctx
->pelf
.ehdr
.e_ident
[EI_CLASS
] == ELFCLASS64
;
473 * 3 sections will be added to the ELF file.
474 * +------------------+
476 * +------------------+
478 * +------------------+
480 * +------------------+
483 /* Create buffer for header and relocations. */
484 rmod_data_size
= sizeof(struct rmodule_header
);
486 rmod_data_size
+= ctx
->nrelocs
* sizeof(Elf64_Addr
);
488 rmod_data_size
+= ctx
->nrelocs
* sizeof(Elf32_Addr
);
490 if (buffer_create(&rmod_data
, rmod_data_size
, "rmod"))
493 buffer_splice(&rmod_header
, &rmod_data
,
494 0, sizeof(struct rmodule_header
));
495 buffer_clone(&relocs
, &rmod_data
);
496 buffer_seek(&relocs
, sizeof(struct rmodule_header
));
498 /* Reset current location. */
499 buffer_set_size(&rmod_header
, 0);
500 buffer_set_size(&relocs
, 0);
502 /* Program contents. */
503 buffer_splice(&program
, in
, ctx
->phdr
->p_offset
, ctx
->phdr
->p_filesz
);
505 /* Create ELF writer with modified entry point. */
506 memcpy(&ehdr
, &ctx
->pelf
.ehdr
, sizeof(ehdr
));
507 ew
= elf_writer_init(&ehdr
);
510 ERROR("Failed to create ELF writer.\n");
511 buffer_delete(&rmod_data
);
515 /* Write out rmodule_header. */
516 ctx
->xdr
->put16(&rmod_header
, RMODULE_MAGIC
);
517 ctx
->xdr
->put8(&rmod_header
, RMODULE_VERSION_1
);
518 ctx
->xdr
->put8(&rmod_header
, 0);
519 /* payload_begin_offset */
520 loc
= sizeof(struct rmodule_header
);
521 ctx
->xdr
->put32(&rmod_header
, loc
);
522 /* payload_end_offset */
523 loc
+= ctx
->phdr
->p_filesz
;
524 ctx
->xdr
->put32(&rmod_header
, loc
);
525 /* relocations_begin_offset */
526 ctx
->xdr
->put32(&rmod_header
, loc
);
527 /* relocations_end_offset */
529 loc
+= ctx
->nrelocs
* sizeof(Elf64_Addr
);
531 loc
+= ctx
->nrelocs
* sizeof(Elf32_Addr
);
532 ctx
->xdr
->put32(&rmod_header
, loc
);
533 /* module_link_start_address */
534 ctx
->xdr
->put32(&rmod_header
, ctx
->phdr
->p_vaddr
);
535 /* module_program_size */
536 ctx
->xdr
->put32(&rmod_header
, ctx
->phdr
->p_memsz
);
537 /* module_entry_point */
538 ctx
->xdr
->put32(&rmod_header
, ctx
->pelf
.ehdr
.e_entry
);
539 /* parameters_begin */
540 ctx
->xdr
->put32(&rmod_header
, ctx
->parameters_begin
);
542 ctx
->xdr
->put32(&rmod_header
, ctx
->parameters_end
);
544 ctx
->xdr
->put32(&rmod_header
, ctx
->bss_begin
);
546 ctx
->xdr
->put32(&rmod_header
, ctx
->bss_end
);
548 ctx
->xdr
->put32(&rmod_header
, 0);
549 ctx
->xdr
->put32(&rmod_header
, 0);
550 ctx
->xdr
->put32(&rmod_header
, 0);
551 ctx
->xdr
->put32(&rmod_header
, 0);
553 /* Write the relocations. */
554 for (unsigned i
= 0; i
< ctx
->nrelocs
; i
++) {
556 ctx
->xdr
->put64(&relocs
, ctx
->emitted_relocs
[i
]);
558 ctx
->xdr
->put32(&relocs
, ctx
->emitted_relocs
[i
]);
565 * There are 2 cases to deal with. The program has a large NOBITS
566 * section and the relocations can fit entirely within occupied memory
567 * region for the program. The other is that the relocations increase
568 * the memory footprint of the program if it was loaded directly into
569 * the region it would run. The rmodule header is a fixed cost that
570 * is considered a part of the program.
572 total_size
+= buffer_size(&rmod_header
);
573 if (buffer_size(&relocs
) + ctx
->phdr
->p_filesz
> ctx
->phdr
->p_memsz
) {
574 total_size
+= buffer_size(&relocs
);
575 total_size
+= ctx
->phdr
->p_filesz
;
577 total_size
+= ctx
->phdr
->p_memsz
;
580 ret
= add_section(ew
, &rmod_header
, ".header", addr
,
581 buffer_size(&rmod_header
));
584 addr
+= buffer_size(&rmod_header
);
586 ret
= add_section(ew
, &program
, ".program", addr
, ctx
->phdr
->p_filesz
);
589 addr
+= ctx
->phdr
->p_filesz
;
592 ret
= add_section(ew
, &relocs
, ".relocs", addr
,
593 buffer_size(&relocs
));
596 addr
+= buffer_size(&relocs
);
599 if (total_size
!= addr
) {
600 ret
= add_section(ew
, NULL
, ".empty", addr
, total_size
- addr
);
606 * Ensure last section has a memory usage that meets the required
607 * total size of the program in memory.
610 ret
= elf_writer_serialize(ew
, out
);
612 ERROR("Failed to serialize ELF to buffer.\n");
615 buffer_delete(&rmod_data
);
616 elf_writer_destroy(ew
);
621 int rmodule_init(struct rmod_context
*ctx
, const struct buffer
*elfin
)
623 struct parsed_elf
*pelf
;
628 memset(ctx
, 0, sizeof(*ctx
));
631 if (parse_elf(elfin
, pelf
, ELF_PARSE_ALL
)) {
632 ERROR("Couldn't parse ELF!\n");
636 /* Only allow executables to be turned into rmodules. */
637 if (pelf
->ehdr
.e_type
!= ET_EXEC
) {
638 ERROR("ELF is not an executable: %u.\n", pelf
->ehdr
.e_type
);
642 /* Determine if architecture is supported. */
643 for (i
= 0; i
< ARRAY_SIZE(reloc_ops
); i
++) {
644 if (reloc_ops
[i
].arch
== pelf
->ehdr
.e_machine
) {
645 ctx
->ops
= &reloc_ops
[i
];
650 if (ctx
->ops
== NULL
) {
651 ERROR("ELF is unsupported arch: %u.\n", pelf
->ehdr
.e_machine
);
655 /* Set the endian ops. */
656 if (ctx
->pelf
.ehdr
.e_ident
[EI_DATA
] == ELFDATA2MSB
)
661 if (find_program_segment(ctx
))
664 if (filter_relocation_sections(ctx
))
673 void rmodule_cleanup(struct rmod_context
*ctx
)
675 free(ctx
->emitted_relocs
);
676 parsed_elf_destroy(&ctx
->pelf
);
679 int rmodule_create(const struct buffer
*elfin
, struct buffer
*elfout
)
681 struct rmod_context ctx
;
684 if (rmodule_init(&ctx
, elfin
))
687 if (rmodule_collect_relocations(&ctx
, NULL
))
690 if (populate_rmodule_info(&ctx
))
693 if (write_elf(&ctx
, elfin
, elfout
))
699 rmodule_cleanup(&ctx
);
703 static void rmod_deserialize(struct rmodule_header
*rmod
, struct buffer
*buff
,
706 rmod
->magic
= xdr
->get16(buff
);
707 rmod
->version
= xdr
->get8(buff
);
708 rmod
->type
= xdr
->get8(buff
);
709 rmod
->payload_begin_offset
= xdr
->get32(buff
);
710 rmod
->payload_end_offset
= xdr
->get32(buff
);
711 rmod
->relocations_begin_offset
= xdr
->get32(buff
);
712 rmod
->relocations_end_offset
= xdr
->get32(buff
);
713 rmod
->module_link_start_address
= xdr
->get32(buff
);
714 rmod
->module_program_size
= xdr
->get32(buff
);
715 rmod
->module_entry_point
= xdr
->get32(buff
);
716 rmod
->parameters_begin
= xdr
->get32(buff
);
717 rmod
->parameters_end
= xdr
->get32(buff
);
718 rmod
->bss_begin
= xdr
->get32(buff
);
719 rmod
->bss_end
= xdr
->get32(buff
);
720 rmod
->padding
[0] = xdr
->get32(buff
);
721 rmod
->padding
[1] = xdr
->get32(buff
);
722 rmod
->padding
[2] = xdr
->get32(buff
);
723 rmod
->padding
[3] = xdr
->get32(buff
);
726 int rmodule_stage_to_elf(Elf64_Ehdr
*ehdr
, struct buffer
*buff
)
728 struct buffer reader
;
729 struct buffer elf_out
;
730 struct rmodule_header rmod
;
732 struct elf_writer
*ew
;
736 const char *section_name
= ".program";
737 const size_t input_sz
= buffer_size(buff
);
739 buffer_clone(&reader
, buff
);
741 xdr
= (ehdr
->e_ident
[EI_DATA
] == ELFDATA2MSB
) ? &xdr_be
: &xdr_le
;
742 bit64
= ehdr
->e_ident
[EI_CLASS
] == ELFCLASS64
;
744 rmod_deserialize(&rmod
, &reader
, xdr
);
746 /* Indicate that file is not an rmodule if initial checks fail. */
747 if (rmod
.magic
!= RMODULE_MAGIC
)
749 if (rmod
.version
!= RMODULE_VERSION_1
)
752 if (rmod
.payload_begin_offset
> input_sz
||
753 rmod
.payload_end_offset
> input_sz
||
754 rmod
.relocations_begin_offset
> input_sz
||
755 rmod
.relocations_end_offset
> input_sz
) {
756 ERROR("Rmodule fields out of bounds.\n");
760 ehdr
->e_entry
= rmod
.module_entry_point
;
761 ew
= elf_writer_init(ehdr
);
766 payload_sz
= rmod
.payload_end_offset
- rmod
.payload_begin_offset
;
767 memset(&shdr
, 0, sizeof(shdr
));
768 shdr
.sh_type
= SHT_PROGBITS
;
769 shdr
.sh_flags
= SHF_WRITE
| SHF_ALLOC
| SHF_EXECINSTR
;
770 shdr
.sh_addr
= rmod
.module_link_start_address
;
771 shdr
.sh_size
= payload_sz
;
772 buffer_splice(&reader
, buff
, rmod
.payload_begin_offset
, payload_sz
);
774 if (elf_writer_add_section(ew
, &shdr
, &reader
, section_name
)) {
775 ERROR("Unable to add ELF section: %s\n", section_name
);
776 elf_writer_destroy(ew
);
780 if (payload_sz
!= rmod
.module_program_size
) {
783 buffer_init(&b
, NULL
, NULL
, 0);
784 memset(&shdr
, 0, sizeof(shdr
));
785 shdr
.sh_type
= SHT_NOBITS
;
786 shdr
.sh_flags
= SHF_WRITE
| SHF_ALLOC
;
787 shdr
.sh_addr
= rmod
.module_link_start_address
+ payload_sz
;
788 shdr
.sh_size
= rmod
.module_program_size
- payload_sz
;
789 if (elf_writer_add_section(ew
, &shdr
, &b
, ".empty")) {
790 ERROR("Unable to add ELF section: .empty\n");
791 elf_writer_destroy(ew
);
796 /* Provide a section symbol so the relcoations can reference that. */
797 if (elf_writer_add_symbol(ew
, section_name
, section_name
, shdr
.sh_addr
,
798 0, STB_LOCAL
, STT_SECTION
)) {
799 ERROR("Unable to add section symbol to ELF.\n");
800 elf_writer_destroy(ew
);
804 /* Add symbols for the parameters if they are non-zero. */
805 if (rmod
.parameters_begin
!= rmod
.parameters_end
) {
808 ret
|= elf_writer_add_symbol(ew
, "_rmodule_params",
810 rmod
.parameters_begin
, 0,
811 STB_GLOBAL
, STT_NOTYPE
);
812 ret
|= elf_writer_add_symbol(ew
, "_ermodule_params",
814 rmod
.parameters_end
, 0,
815 STB_GLOBAL
, STT_NOTYPE
);
818 ERROR("Unable to add module params symbols to ELF\n");
819 elf_writer_destroy(ew
);
824 if (elf_writer_add_symbol(ew
, "_bss", section_name
, rmod
.bss_begin
, 0,
825 STB_GLOBAL
, STT_NOTYPE
) ||
826 elf_writer_add_symbol(ew
, "_ebss", section_name
, rmod
.bss_end
, 0,
827 STB_GLOBAL
, STT_NOTYPE
)) {
828 ERROR("Unable to add bss symbols to ELF\n");
829 elf_writer_destroy(ew
);
833 ssize_t relocs_sz
= rmod
.relocations_end_offset
;
834 relocs_sz
-= rmod
.relocations_begin_offset
;
835 buffer_splice(&reader
, buff
, rmod
.relocations_begin_offset
, relocs_sz
);
836 while (relocs_sz
> 0) {
840 relocs_sz
-= sizeof(Elf64_Addr
);
841 addr
= xdr
->get64(&reader
);
843 relocs_sz
-= sizeof(Elf32_Addr
);
844 addr
= xdr
->get32(&reader
);
847 /* Skip any relocations that are below the link address. */
848 if (addr
< rmod
.module_link_start_address
)
851 if (elf_writer_add_rel(ew
, section_name
, addr
)) {
852 ERROR("Relocation addition failure.\n");
853 elf_writer_destroy(ew
);
858 if (elf_writer_serialize(ew
, &elf_out
)) {
859 ERROR("ELF writer serialize failure.\n");
860 elf_writer_destroy(ew
);
864 elf_writer_destroy(ew
);
866 /* Flip buffer with the created ELF one. */