]>
git.proxmox.com Git - efi-boot-shim.git/blob - buildid.c
1 // SPDX-License-Identifier: BSD-2-Clause-Patent
4 * Walk a list of input files, printing the name and buildid of any file
20 static Elf_Scn
*get_scn_named(Elf
* elf
, char *goal
, GElf_Shdr
* shdrp_out
)
26 GElf_Shdr shdr_data
, *shdrp
;
28 shdrp
= shdrp_out
? shdrp_out
: &shdr_data
;
30 rc
= elf_getshdrstrndx(elf
, &shstrndx
);
38 scn
= elf_getscn(elf
, ++scn_no
);
42 shdr
= gelf_getshdr(scn
, shdrp
);
45 * the binary is malformed, but hey, maybe the next
46 * one is fine, why not...
50 name
= elf_strptr(elf
, shstrndx
, shdr
->sh_name
);
51 if (name
&& !strcmp(name
, goal
))
53 } while (scn
!= NULL
);
57 static void *get_buildid(Elf
* elf
, size_t * sz
)
65 scn
= get_scn_named(elf
, ".note.gnu.build-id", &shdr
);
69 data
= elf_getdata(scn
, NULL
);
79 notesz
= gelf_getnote(data
, offset
, &nhdr
, &nameoff
, &descoff
);
84 if (nhdr
.n_type
!= NT_GNU_BUILD_ID
)
87 name
= data
->d_buf
+ nameoff
;
88 if (!name
|| strcmp(name
, ELF_NOTE_GNU
))
92 return data
->d_buf
+ descoff
;
97 static void data2hex(uint8_t * data
, size_t ds
, char *str
)
99 const char hex
[] = "0123456789abcdef";
102 for (d
= 0, s
= 0; d
< ds
; d
+= 1, s
+= 2) {
103 str
[s
+ 0] = hex
[(data
[d
] >> 4) & 0x0f];
104 str
[s
+ 1] = hex
[(data
[d
] >> 0) & 0x0f];
109 static void handle_one(char *f
)
118 if (!strcmp(f
, "-")) {
121 if ((elf
= elf_begin(fd
, ELF_C_READ
, NULL
)) == NULL
)
122 errx(1, "Couldn't read ELF data from \"%s\"", f
);
124 if ((fd
= open(f
, O_RDONLY
)) < 0)
125 err(1, "Couldn't open \"%s\"", f
);
127 if ((elf
= elf_begin(fd
, ELF_C_READ_MMAP
, NULL
)) == NULL
)
128 errx(1, "Couldn't read ELF data from \"%s\"", f
);
131 data
= get_buildid(elf
, &sz
);
133 b
= alloca(sz
* 2 + 1);
134 data2hex(data
, sz
, b
);
136 written
= write(1, f
, strlen(f
));
138 errx(1, "Error writing build id");
139 written
= write(1, " ", 1);
140 written
= write(1, b
, strlen(b
));
142 errx(1, "Error writing build id");
143 written
= write(1, "\n", 1);
151 __attribute__ ((__noreturn__
))
154 FILE *out
= status
? stderr
: stdout
;
156 fprintf(out
, "Usage: buildid [ flags | file0 [file1 [.. fileN]]]\n");
157 fprintf(out
, "Flags:\n");
158 fprintf(out
, " -h Print this help text and exit\n");
163 int main(int argc
, char **argv
)
166 struct option options
[] = {
177 while ((i
= getopt_long(argc
, argv
, "h", options
, &longindex
)) != -1) {
181 usage(longindex
== -1 ? 1 : 0);
186 elf_version(EV_CURRENT
);
191 for (i
= optind
; i
< argc
; i
++)
197 // vim:fenc=utf-8:tw=75