build_id: Provide ld-embedded build-ids

This patch enables the Elf to be built with the build-id
and provide in the Xen hypervisor the code to extract it.

The man-page for ld --build-id says it is:

"Request the creation of a ".note.gnu.build-id" ELF note
section or a ".build-id" COFF section.  The contents of the
note are unique bits identifying this linked file. style can be
"uuid" to use 128 random bits, "sha1" to use a 160-bit SHA1 hash
on the normative parts of the output contents, ..."

One can also retrieve the value of the build-id by doing
'readelf -n xen-syms'.

For EFI builds we re-use the same build-id that the xen-syms
was built with.

The version of ld that first implemented --build-id is v2.18.
We check for to see if the linker supports the --build-id
parameter and if so use it.

For x86 we have two binaries - the xen-syms and the xen - an
smaller version with lots of sections removed. To make it possible
for readelf -n xen we also modify mkelf32 and xen.lds.S to include
the PT_NOTE ELF section.

The EFI binary is more complicated. We only build one type of
binary and expanding the amount of sections the EFI binary has to
include an .note one is pointless - as there is no concept of
PT_NOTE. The best we can do is move this .note in the .rodata section.

Further development wise should move it to .buildid section
so that DataDirectory debug data nor CodeView can view it.
(The author has no clue what those are).

Note that in earlier patches the linker script had:

 __note_gnu_build_id_start = .;
 *(.rodata.note.gnu.build-id)
 __note_gnu_build_id_end = .;
 *(.note)
 *(.note.*)

Which meant you could have different ELF notes _outside_ the
__note_gnu_build_id_end. However for EFI builds we take the whole
.note* section and jam it in the EFI to be between
__note_gnu_build_id_start and __note_gnu_build_id_end.
To not make this happend we make on the ELF build the section
be called .note.gnu.build-id  (instead of just .note).
If there is a need for a different type of note other folks
can add it as a different section name.

Note that we do call --binary-id=sha1 on all linker invocations.
We have to do to enforce that the symbol offsets don't changes
(the side effect is that we we would have multiple binary ids -
except that the last one is the final one).

Without this working the symbol table embedded in Xen ends
up incorrect - some of the values it contains would be offset by the
size of the included build id.

This obviously causes problems when resolving symbols.

We also define the NT_GNU_BUILD_ID in the elfstructs.h as we
need to use it in various places.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Martin Pohlack <mpohlack@amazon.de>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
Konrad Rzeszutek Wilk committed 2016-04-29 03:59:03 -04:00
1 parent f8a10174e8
commit a353cab905
9 files changed
+258 -28

No files matched your search

+11
View File
@@ -135,6 +135,17 @@ endef
check-$(gcc) = $(call cc-ver-check,CC,0x040100,"Xen requires at least gcc-4.1") check-$(gcc) = $(call cc-ver-check,CC,0x040100,"Xen requires at least gcc-4.1")
$(eval $(check-y)) $(eval $(check-y))
ld-ver-build-id = $(shell $(1) --build-id 2>&1 | \
grep -q build-id && echo n || echo y)
export XEN_HAS_BUILD_ID ?= n
ifeq ($(call ld-ver-build-id,$(LD)),n)
build_id_linker :=
else
CFLAGS += -DBUILD_ID
build_id_linker := --build-id=sha1
endif
# as-insn: Check whether assembler supports an instruction. # as-insn: Check whether assembler supports an instruction.
# Usage: cflags-y += $(call as-insn "insn",option-yes,option-no) # Usage: cflags-y += $(call as-insn "insn",option-yes,option-no)
as-insn = $(if $(shell echo 'void _(void) { asm volatile ( $(2) ); }' \ as-insn = $(if $(shell echo 'void _(void) { asm volatile ( $(2) ); }' \
+1 -1
View File
@@ -93,7 +93,7 @@ $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o
$(NM) -pa --format=sysv $(@D)/.$(@F).1 \ $(NM) -pa --format=sysv $(@D)/.$(@F).1 \
| $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).1.S | $(BASEDIR)/tools/symbols --sysv --sort >$(@D)/.$(@F).1.S
$(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o
$(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(LD) $(LDFLAGS) -T xen.lds -N prelink.o $(build_id_linker) \
$(@D)/.$(@F).1.o -o $@ $(@D)/.$(@F).1.o -o $@
rm -f $(@D)/.$(@F).[0-9]* rm -f $(@D)/.$(@F).[0-9]*
+13 -2
View File
@@ -22,6 +22,9 @@ OUTPUT_ARCH(FORMAT)
PHDRS PHDRS
{ {
text PT_LOAD /* XXX should be AT ( XEN_PHYS_START ) */ ; text PT_LOAD /* XXX should be AT ( XEN_PHYS_START ) */ ;
#if defined(BUILD_ID)
note PT_NOTE ;
#endif
} }
SECTIONS SECTIONS
{ {
@@ -57,10 +60,18 @@ SECTIONS
*(.lockprofile.data) *(.lockprofile.data)
__lock_profile_end = .; __lock_profile_end = .;
#endif #endif
_erodata = .; /* End of read-only data */
} :text } :text
#if defined(BUILD_ID)
. = ALIGN(4);
.note.gnu.build-id : {
__note_gnu_build_id_start = .;
*(.note.gnu.build-id)
__note_gnu_build_id_end = .;
} :note :text
#endif
_erodata = .; /* End of read-only data */
.data : { /* Data */ .data : { /* Data */
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
*(.data.page_aligned) *(.data.page_aligned)
+25 -5
View File
@@ -74,6 +74,12 @@ efi-y := $(shell if [ ! -r $(BASEDIR)/include/xen/compile.h -o \
-O $(BASEDIR)/include/xen/compile.h ]; then \ -O $(BASEDIR)/include/xen/compile.h ]; then \
echo '$(TARGET).efi'; fi) echo '$(TARGET).efi'; fi)
ifneq ($(build_id_linker),)
notes_phdrs = --notes
else
notes_phdrs =
endif
ifdef CONFIG_XSPLICE ifdef CONFIG_XSPLICE
all_symbols = --all-symbols all_symbols = --all-symbols
ifdef CONFIG_FAST_SYMBOL_LOOKUP ifdef CONFIG_FAST_SYMBOL_LOOKUP
@@ -84,7 +90,7 @@ all_symbols =
endif endif
$(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32 $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32
./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \ ./boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TARGET) 0x100000 \
`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'` `$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
.PHONY: tests .PHONY: tests
@@ -119,22 +125,28 @@ $(BASEDIR)/common/symbols-dummy.o:
$(MAKE) -f $(BASEDIR)/Rules.mk -C $(BASEDIR)/common symbols-dummy.o $(MAKE) -f $(BASEDIR)/Rules.mk -C $(BASEDIR)/common symbols-dummy.o
$(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o $(TARGET)-syms: prelink.o xen.lds $(BASEDIR)/common/symbols-dummy.o
$(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(LD) $(LDFLAGS) -T xen.lds -N prelink.o $(build_id_linker) \
$(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0 $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0
$(NM) -pa --format=sysv $(@D)/.$(@F).0 \ $(NM) -pa --format=sysv $(@D)/.$(@F).0 \
| $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort \ | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort \
>$(@D)/.$(@F).0.S >$(@D)/.$(@F).0.S
$(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o
$(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(LD) $(LDFLAGS) -T xen.lds -N prelink.o $(build_id_linker) \
$(@D)/.$(@F).0.o -o $(@D)/.$(@F).1 $(@D)/.$(@F).0.o -o $(@D)/.$(@F).1
$(NM) -pa --format=sysv $(@D)/.$(@F).1 \ $(NM) -pa --format=sysv $(@D)/.$(@F).1 \
| $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort --warn-dup \ | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort --warn-dup \
>$(@D)/.$(@F).1.S >$(@D)/.$(@F).1.S
$(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o
$(LD) $(LDFLAGS) -T xen.lds -N prelink.o \ $(LD) $(LDFLAGS) -T xen.lds -N prelink.o $(build_id_linker) \
$(@D)/.$(@F).1.o -o $@ $(@D)/.$(@F).1.o -o $@
rm -f $(@D)/.$(@F).[0-9]* rm -f $(@D)/.$(@F).[0-9]*
note.o: $(TARGET)-syms
$(OBJCOPY) -O binary --only-section=.note.gnu.build-id $(BASEDIR)/xen-syms $@.bin
$(OBJCOPY) -I binary -O elf64-x86-64 -B i386:x86-64 \
--rename-section=.data=.note.gnu.build-id -S $@.bin $@
rm -f $@.bin
EFI_LDFLAGS = $(patsubst -m%,-mi386pep,$(LDFLAGS)) --subsystem=10 EFI_LDFLAGS = $(patsubst -m%,-mi386pep,$(LDFLAGS)) --subsystem=10
EFI_LDFLAGS += --image-base=$(1) --stack=0,0 --heap=0,0 --strip-debug EFI_LDFLAGS += --image-base=$(1) --stack=0,0 --heap=0,0 --strip-debug
EFI_LDFLAGS += --section-alignment=0x200000 --file-alignment=0x20 EFI_LDFLAGS += --section-alignment=0x200000 --file-alignment=0x20
@@ -147,6 +159,13 @@ $(TARGET).efi: VIRT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A VIR
$(TARGET).efi: ALT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A ALT_START$$,,p') $(TARGET).efi: ALT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A ALT_START$$,,p')
# Don't use $(wildcard ...) here - at least make 3.80 expands this too early! # Don't use $(wildcard ...) here - at least make 3.80 expands this too early!
$(TARGET).efi: guard = $(if $(shell echo efi/dis* | grep disabled),:) $(TARGET).efi: guard = $(if $(shell echo efi/dis* | grep disabled),:)
ifneq ($(build_id_linker),)
$(TARGET).efi: note.o
note_file := note.o
else
note_file :=
endif
$(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbols-dummy.o efi/mkreloc $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbols-dummy.o efi/mkreloc
$(foreach base, $(VIRT_BASE) $(ALT_BASE), \ $(foreach base, $(VIRT_BASE) $(ALT_BASE), \
$(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \ $(guard) $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \
@@ -163,7 +182,7 @@ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbol
| $(guard) $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).1s.S | $(guard) $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).1s.S
$(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(guard) $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o
$(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \ $(guard) $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \
$(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o -o $@ $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(note_file) -o $@
if $(guard) false; then rm -f $@; echo 'EFI support disabled'; fi if $(guard) false; then rm -f $@; echo 'EFI support disabled'; fi
rm -f $(@D)/.$(@F).[0-9]* rm -f $(@D)/.$(@F).[0-9]*
@@ -195,4 +214,5 @@ clean::
rm -f $(BASEDIR)/.xen-syms.[0-9]* boot/.*.d rm -f $(BASEDIR)/.xen-syms.[0-9]* boot/.*.d
rm -f $(BASEDIR)/.xen.efi.[0-9]* efi/*.o efi/.*.d efi/*.efi efi/disabled efi/mkreloc rm -f $(BASEDIR)/.xen.efi.[0-9]* efi/*.o efi/.*.d efi/*.efi efi/disabled efi/mkreloc
rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin
rm -f note.o
$(MAKE) -f $(BASEDIR)/Rules.mk -C test clean $(MAKE) -f $(BASEDIR)/Rules.mk -C test clean
+123 -19
View File
@@ -45,9 +45,9 @@ static Elf32_Ehdr out_ehdr = {
0, /* e_flags */ 0, /* e_flags */
sizeof(Elf32_Ehdr), /* e_ehsize */ sizeof(Elf32_Ehdr), /* e_ehsize */
sizeof(Elf32_Phdr), /* e_phentsize */ sizeof(Elf32_Phdr), /* e_phentsize */
1, /* e_phnum */ 1, /* modify based on num_phdrs */ /* e_phnum */
sizeof(Elf32_Shdr), /* e_shentsize */ sizeof(Elf32_Shdr), /* e_shentsize */
3, /* e_shnum */ 3, /* modify based on num_phdrs */ /* e_shnum */
2 /* e_shstrndx */ 2 /* e_shstrndx */
}; };
@@ -61,8 +61,20 @@ static Elf32_Phdr out_phdr = {
PF_R|PF_W|PF_X, /* p_flags */ PF_R|PF_W|PF_X, /* p_flags */
64 /* p_align */ 64 /* p_align */
}; };
static Elf32_Phdr note_phdr = {
PT_NOTE, /* p_type */
DYNAMICALLY_FILLED, /* p_offset */
DYNAMICALLY_FILLED, /* p_vaddr */
DYNAMICALLY_FILLED, /* p_paddr */
DYNAMICALLY_FILLED, /* p_filesz */
DYNAMICALLY_FILLED, /* p_memsz */
PF_R, /* p_flags */
4 /* p_align */
};
static u8 out_shstrtab[] = "\0.text\0.shstrtab"; static u8 out_shstrtab[] = "\0.text\0.shstrtab";
/* If num_phdrs >= 2, we need to tack the .note. */
static u8 out_shstrtab_extra[] = ".note\0";
static Elf32_Shdr out_shdr[] = { static Elf32_Shdr out_shdr[] = {
{ 0 }, { 0 },
@@ -90,6 +102,23 @@ static Elf32_Shdr out_shdr[] = {
} }
}; };
/*
* The 17 points to the '.note' in the out_shstrtab and out_shstrtab_extra
* laid out in the file.
*/
static Elf32_Shdr out_shdr_note = {
17, /* sh_name */
SHT_NOTE, /* sh_type */
0, /* sh_flags */
DYNAMICALLY_FILLED, /* sh_addr */
DYNAMICALLY_FILLED, /* sh_offset */
DYNAMICALLY_FILLED, /* sh_size */
0, /* sh_link */
0, /* sh_info */
4, /* sh_addralign */
0 /* sh_entsize */
};
/* Some system header files define these macros and pollute our namespace. */ /* Some system header files define these macros and pollute our namespace. */
#undef swap16 #undef swap16
#undef swap32 #undef swap32
@@ -228,28 +257,34 @@ static void do_read(int fd, void *data, int len)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
u64 final_exec_addr; u64 final_exec_addr;
u32 loadbase, dat_siz, mem_siz; u32 loadbase, dat_siz, mem_siz, note_base, note_sz, offset;
char *inimage, *outimage; char *inimage, *outimage;
int infd, outfd; int infd, outfd;
char buffer[1024]; char buffer[1024];
int bytes, todo, i; int bytes, todo, i = 1;
int num_phdrs = 1;
Elf32_Ehdr in32_ehdr; Elf32_Ehdr in32_ehdr;
Elf64_Ehdr in64_ehdr; Elf64_Ehdr in64_ehdr;
Elf64_Phdr in64_phdr; Elf64_Phdr in64_phdr;
if ( argc != 5 ) if ( argc < 5 )
{ {
fprintf(stderr, "Usage: mkelf32 <in-image> <out-image> " fprintf(stderr, "Usage: mkelf32 [--notes] <in-image> <out-image> "
"<load-base> <final-exec-addr>\n"); "<load-base> <final-exec-addr>\n");
return 1; return 1;
} }
inimage = argv[1]; if ( !strcmp(argv[1], "--notes") )
outimage = argv[2]; {
loadbase = strtoul(argv[3], NULL, 16); i = 2;
final_exec_addr = strtoull(argv[4], NULL, 16); num_phdrs = 2;
}
inimage = argv[i++];
outimage = argv[i++];
loadbase = strtoul(argv[i++], NULL, 16);
final_exec_addr = strtoull(argv[i++], NULL, 16);
infd = open(inimage, O_RDONLY); infd = open(inimage, O_RDONLY);
if ( infd == -1 ) if ( infd == -1 )
@@ -285,11 +320,10 @@ int main(int argc, char **argv)
(int)in64_ehdr.e_phentsize, (int)sizeof(in64_phdr)); (int)in64_ehdr.e_phentsize, (int)sizeof(in64_phdr));
return 1; return 1;
} }
if ( in64_ehdr.e_phnum != num_phdrs )
if ( in64_ehdr.e_phnum != 1 )
{ {
fprintf(stderr, "Expect precisly 1 program header; found %d.\n", fprintf(stderr, "Expect precisly %d program header; found %d.\n",
(int)in64_ehdr.e_phnum); num_phdrs, (int)in64_ehdr.e_phnum);
return 1; return 1;
} }
@@ -304,6 +338,32 @@ int main(int argc, char **argv)
/*mem_siz = (u32)in64_phdr.p_memsz;*/ /*mem_siz = (u32)in64_phdr.p_memsz;*/
mem_siz = (u32)(final_exec_addr - in64_phdr.p_vaddr); mem_siz = (u32)(final_exec_addr - in64_phdr.p_vaddr);
note_sz = note_base = offset = 0;
if ( num_phdrs > 1 )
{
offset = in64_phdr.p_offset;
note_base = in64_phdr.p_vaddr;
(void)lseek(infd, in64_ehdr.e_phoff+sizeof(in64_phdr), SEEK_SET);
do_read(infd, &in64_phdr, sizeof(in64_phdr));
endianadjust_phdr64(&in64_phdr);
(void)lseek(infd, offset, SEEK_SET);
note_sz = in64_phdr.p_memsz;
note_base = in64_phdr.p_vaddr - note_base;
if ( in64_phdr.p_offset > dat_siz || offset > in64_phdr.p_offset )
{
fprintf(stderr, "Expected .note section within .text section!\n" \
"Offset %ld not within %d!\n",
in64_phdr.p_offset, dat_siz);
return 1;
}
/* Gets us the absolute offset within the .text section. */
offset = in64_phdr.p_offset - offset;
}
/* /*
* End the image on a page boundary. This gets round alignment bugs * End the image on a page boundary. This gets round alignment bugs
* in the boot- or chain-loader (e.g., kexec on the XenoBoot CD). * in the boot- or chain-loader (e.g., kexec on the XenoBoot CD).
@@ -322,6 +382,31 @@ int main(int argc, char **argv)
out_shdr[1].sh_size = dat_siz; out_shdr[1].sh_size = dat_siz;
out_shdr[2].sh_offset = RAW_OFFSET + dat_siz + sizeof(out_shdr); out_shdr[2].sh_offset = RAW_OFFSET + dat_siz + sizeof(out_shdr);
if ( num_phdrs > 1 )
{
/* We have two of them! */
out_ehdr.e_phnum = num_phdrs;
/* Extra .note section. */
out_ehdr.e_shnum++;
/* Fill out the PT_NOTE program header. */
note_phdr.p_vaddr = note_base;
note_phdr.p_paddr = note_base;
note_phdr.p_filesz = note_sz;
note_phdr.p_memsz = note_sz;
note_phdr.p_offset = offset;
/* Tack on the .note\0 */
out_shdr[2].sh_size += sizeof(out_shstrtab_extra);
/* And move it past the .note section. */
out_shdr[2].sh_offset += sizeof(out_shdr_note);
/* Fill out the .note section. */
out_shdr_note.sh_size = note_sz;
out_shdr_note.sh_addr = note_base;
out_shdr_note.sh_offset = RAW_OFFSET + offset;
}
outfd = open(outimage, O_WRONLY|O_CREAT|O_TRUNC, 0775); outfd = open(outimage, O_WRONLY|O_CREAT|O_TRUNC, 0775);
if ( outfd == -1 ) if ( outfd == -1 )
{ {
@@ -335,8 +420,14 @@ int main(int argc, char **argv)
endianadjust_phdr32(&out_phdr); endianadjust_phdr32(&out_phdr);
do_write(outfd, &out_phdr, sizeof(out_phdr)); do_write(outfd, &out_phdr, sizeof(out_phdr));
if ( (bytes = RAW_OFFSET - sizeof(out_ehdr) - sizeof(out_phdr)) < 0 ) if ( num_phdrs > 1 )
{
endianadjust_phdr32(&note_phdr);
do_write(outfd, &note_phdr, sizeof(note_phdr));
}
if ( (bytes = RAW_OFFSET - sizeof(out_ehdr) - (num_phdrs * sizeof(out_phdr)) ) < 0 )
{ {
fprintf(stderr, "Header overflow.\n"); fprintf(stderr, "Header overflow.\n");
return 1; return 1;
@@ -355,9 +446,22 @@ int main(int argc, char **argv)
endianadjust_shdr32(&out_shdr[i]); endianadjust_shdr32(&out_shdr[i]);
do_write(outfd, &out_shdr[0], sizeof(out_shdr)); do_write(outfd, &out_shdr[0], sizeof(out_shdr));
do_write(outfd, out_shstrtab, sizeof(out_shstrtab)); if ( num_phdrs > 1 )
do_write(outfd, buffer, 4-((sizeof(out_shstrtab)+dat_siz)&3)); {
endianadjust_shdr32(&out_shdr_note);
/* Append the .note section. */
do_write(outfd, &out_shdr_note, sizeof(out_shdr_note));
/* The normal strings - .text\0.. */
do_write(outfd, out_shstrtab, sizeof(out_shstrtab));
/* Our .note */
do_write(outfd, out_shstrtab_extra, sizeof(out_shstrtab_extra));
do_write(outfd, buffer, 4-((sizeof(out_shstrtab)+sizeof(out_shstrtab_extra)+dat_siz)&3));
}
else
{
do_write(outfd, out_shstrtab, sizeof(out_shstrtab));
do_write(outfd, buffer, 4-((sizeof(out_shstrtab)+dat_siz)&3));
}
close(infd); close(infd);
close(outfd); close(outfd);
+29 -1
View File
@@ -31,6 +31,9 @@ OUTPUT_ARCH(i386:x86-64)
PHDRS PHDRS
{ {
text PT_LOAD ; text PT_LOAD ;
#if defined(BUILD_ID) && !defined(EFI)
note PT_NOTE ;
#endif
} }
SECTIONS SECTIONS
{ {
@@ -79,6 +82,16 @@ SECTIONS
*(.rodata) *(.rodata)
*(.rodata.*) *(.rodata.*)
#if defined(BUILD_ID) && defined(EFI)
/*
* No mechanism to put an PT_NOTE in the EFI file - so put
* it in .rodata section. (notes.o supplies us with .note.gnu.build-id).
*/
. = ALIGN(4);
__note_gnu_build_id_start = .;
*(.note.gnu.build-id)
__note_gnu_build_id_end = .;
#endif
. = ALIGN(8); . = ALIGN(8);
/* Exception table */ /* Exception table */
__start___ex_table = .; __start___ex_table = .;
@@ -96,9 +109,24 @@ SECTIONS
*(.lockprofile.data) *(.lockprofile.data)
__lock_profile_end = .; __lock_profile_end = .;
#endif #endif
_erodata = .;
} :text } :text
#if defined(BUILD_ID) && !defined(EFI)
/*
* What a strange section name. The reason is that on ELF builds this section
* is extracted to notes.o (which then is ingested in the EFI file). But the
* compiler may want to inject other things in the .note which we don't care
* about - hence this unique name.
*/
. = ALIGN(4);
.note.gnu.build-id : {
__note_gnu_build_id_start = .;
*(.note.gnu.build-id)
__note_gnu_build_id_end = .;
} :note :text
#endif
_erodata = .;
#ifdef EFI #ifdef EFI
. = ALIGN(MB(2)); . = ALIGN(MB(2));
#else #else
+52
View File
@@ -1,6 +1,13 @@
#include <xen/compile.h> #include <xen/compile.h>
#include <xen/init.h>
#include <xen/errno.h>
#include <xen/string.h>
#include <xen/types.h>
#include <xen/elf.h>
#include <xen/version.h> #include <xen/version.h>
#include <asm/cache.h>
const char *xen_compile_date(void) const char *xen_compile_date(void)
{ {
return XEN_COMPILE_DATE; return XEN_COMPILE_DATE;
@@ -61,6 +68,51 @@ const char *xen_deny(void)
return "<denied>"; return "<denied>";
} }
static const void *build_id_p __read_mostly;
static unsigned int build_id_len __read_mostly;
int xen_build_id(const void **p, unsigned int *len)
{
if ( !build_id_len )
return -ENODATA;
*len = build_id_len;
*p = build_id_p;
return 0;
}
#ifdef BUILD_ID
/* Defined in linker script. */
extern const Elf_Note __note_gnu_build_id_start[], __note_gnu_build_id_end[];
static int __init xen_build_init(void)
{
const Elf_Note *n = __note_gnu_build_id_start;
/* --build-id invoked with wrong parameters. */
if ( __note_gnu_build_id_end <= &n[0] )
return -ENODATA;
/* Check for full Note header. */
if ( &n[1] > __note_gnu_build_id_end )
return -ENODATA;;
/* Check if we really have a build-id. */
if ( NT_GNU_BUILD_ID != n->type )
return -ENODATA;
/* Sanity check, name should be "GNU" for ld-generated build-id. */
if ( strncmp(ELFNOTE_NAME(n), "GNU", n->namesz) != 0 )
return -ENODATA;
build_id_len = n->descsz;
build_id_p = ELFNOTE_DESC(n);
return 0;
}
__initcall(xen_build_init);
#endif
/* /*
* Local variables: * Local variables:
* mode: C * mode: C
+3
View File
@@ -40,6 +40,9 @@ typedef uint32_t Elf64_Word;
typedef int64_t Elf64_Sxword; typedef int64_t Elf64_Sxword;
typedef uint64_t Elf64_Xword; typedef uint64_t Elf64_Xword;
/* Unique build id string format when using --build-id. */
#define NT_GNU_BUILD_ID 3
/* /*
* e_ident[] identification indexes * e_ident[] identification indexes
* See http://www.caldera.com/developers/gabi/2000-07-17/ch4.eheader.html * See http://www.caldera.com/developers/gabi/2000-07-17/ch4.eheader.html
+1
View File
@@ -13,5 +13,6 @@ const char *xen_extra_version(void);
const char *xen_changeset(void); const char *xen_changeset(void);
const char *xen_banner(void); const char *xen_banner(void);
const char *xen_deny(void); const char *xen_deny(void);
int xen_build_id(const void **p, unsigned int *len);
#endif /* __XEN_VERSION_H__ */ #endif /* __XEN_VERSION_H__ */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.