coreboot-kgpe-d16/util/cbfstool/cbfs-mkpayload.c

424 lines
11 KiB
C
Raw Normal View History

/*
* cbfs-mkpayload
*
* Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
* 2009 coresystems GmbH
* written by Patrick Georgi <patrick.georgi@coresystems.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elfparsing.h"
#include "common.h"
#include "cbfs.h"
#include "fv.h"
#include "coff.h"
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
/* serialize the seg array into the buffer.
* The buffer is assumed to be large enough.
*/
void xdr_segs(struct buffer *output,
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
struct cbfs_payload_segment *segs, int nseg)
{
struct buffer outheader;
int i;
outheader.data = output->data;
outheader.size = 0;
for(i = 0; i < nseg; i++){
xdr_be.put32(&outheader, segs[i].type);
xdr_be.put32(&outheader, segs[i].compression);
xdr_be.put32(&outheader, segs[i].offset);
xdr_be.put64(&outheader, segs[i].load_addr);
xdr_be.put32(&outheader, segs[i].len);
xdr_be.put32(&outheader, segs[i].mem_len);
}
}
void xdr_get_seg(struct cbfs_payload_segment *out,
struct cbfs_payload_segment *in)
{
struct buffer inheader;
inheader.data = (void *)in;
inheader.size = sizeof(*in);
out->type = xdr_be.get32(&inheader);
out->compression = xdr_be.get32(&inheader);
out->offset = xdr_be.get32(&inheader);
out->load_addr = xdr_be.get64(&inheader);
out->len = xdr_be.get32(&inheader);
out->mem_len = xdr_be.get32(&inheader);
}
cbfstool: Clean up in preparation for adding new files This enables more warnings on the cbfstool codebase and fixes the issues that surface as a result. A memory leak that used to occur when compressing files with lzma is also found and fixed. Finally, there are several fixes for the Makefile: - Its autodependencies used to be broken because the target for the .dependencies file was misnamed; this meant that Make didn't know how to rebuild the file, and so would silently skip the step of updating it before including it. - The ability to build to a custom output directory by defining the obj variable had bitrotted. - The default value of the obj variable was causing implicit rules not to apply when specifying a file as a target without providing a custom value for obj. - Add a distclean target for removing the .dependencies file. BUG=chromium:461875 TEST=Build an image with cbfstool both before and after. BRANCH=None Change-Id: I951919d63443f2b053c2e67c1ac9872abc0a43ca Signed-off-by: Sol Boucher <solb@chromium.org> Original-Commit-Id: 49293443b4e565ca48d284e9a66f80c9c213975d Original-Change-Id: Ia7350c2c3306905984cfa711d5fc4631f0b43d5b Original-Signed-off-by: Sol Boucher <solb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/257340 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-on: http://review.coreboot.org/9937 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-06 00:38:03 +01:00
int parse_elf_to_payload(const struct buffer *input, struct buffer *output,
comp_algo algo)
{
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
Elf64_Phdr *phdr;
Elf64_Ehdr ehdr;
Elf64_Shdr *shdr;
char *header;
char *strtab;
int headers;
int segments = 1;
int isize = 0, osize = 0;
int doffset = 0;
struct cbfs_payload_segment *segs = NULL;
int i;
int ret = 0;
comp_func_ptr compress = compression_function(algo);
if (!compress)
return -1;
cbfstool: Clean up in preparation for adding new files This enables more warnings on the cbfstool codebase and fixes the issues that surface as a result. A memory leak that used to occur when compressing files with lzma is also found and fixed. Finally, there are several fixes for the Makefile: - Its autodependencies used to be broken because the target for the .dependencies file was misnamed; this meant that Make didn't know how to rebuild the file, and so would silently skip the step of updating it before including it. - The ability to build to a custom output directory by defining the obj variable had bitrotted. - The default value of the obj variable was causing implicit rules not to apply when specifying a file as a target without providing a custom value for obj. - Add a distclean target for removing the .dependencies file. BUG=chromium:461875 TEST=Build an image with cbfstool both before and after. BRANCH=None Change-Id: I951919d63443f2b053c2e67c1ac9872abc0a43ca Signed-off-by: Sol Boucher <solb@chromium.org> Original-Commit-Id: 49293443b4e565ca48d284e9a66f80c9c213975d Original-Change-Id: Ia7350c2c3306905984cfa711d5fc4631f0b43d5b Original-Signed-off-by: Sol Boucher <solb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/257340 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-on: http://review.coreboot.org/9937 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-06 00:38:03 +01:00
if (elf_headers(input, &ehdr, &phdr, &shdr) < 0)
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
return -1;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
DEBUG("start: parse_elf_to_payload\n");
headers = ehdr.e_phnum;
header = input->data;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
strtab = &header[shdr[ehdr.e_shstrndx].sh_offset];
/* Count the number of headers - look for the .notes.pinfo
* section */
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
for (i = 0; i < ehdr.e_shnum; i++) {
char *name;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
if (i == ehdr.e_shstrndx)
continue;
if (shdr[i].sh_size == 0)
continue;
name = (char *)(strtab + shdr[i].sh_name);
if (!strcmp(name, ".note.pinfo")) {
segments++;
isize += (unsigned int)shdr[i].sh_size;
}
}
/* Now, regular headers - we only care about PT_LOAD headers,
* because thats what we're actually going to load
*/
for (i = 0; i < headers; i++) {
if (phdr[i].p_type != PT_LOAD)
continue;
/* Empty segments are never interesting */
if (phdr[i].p_memsz == 0)
continue;
isize += phdr[i].p_filesz;
segments++;
}
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
/* allocate the segment header array */
segs = calloc(segments, sizeof(*segs));
if (segs == NULL) {
ret = -1;
goto out;
}
/* Allocate a block of memory to store the data in */
if (buffer_create(output, (segments * sizeof(*segs)) + isize,
input->name) != 0) {
ret = -1;
goto out;
}
memset(output->data, 0, output->size);
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
doffset = (segments * sizeof(*segs));
/* set up for output marshaling. This is a bit
* tricky as we are marshaling the headers at the front,
* and the data starting after the headers. We need to convert
* the headers to the right format but the data
* passes through unchanged. Unlike most XDR code,
* we are doing these two concurrently. The doffset is
* used to compute the address for the raw data, and the
* outheader is used to marshal the headers. To make it simpler
* for The Reader, we set up the headers in a separate array,
* then marshal them all at once to the output.
*/
segments = 0;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
for (i = 0; i < ehdr.e_shnum; i++) {
char *name;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
if (i == ehdr.e_shstrndx)
continue;
if (shdr[i].sh_size == 0)
continue;
name = (char *)(strtab + shdr[i].sh_name);
if (!strcmp(name, ".note.pinfo")) {
segs[segments].type = PAYLOAD_SEGMENT_PARAMS;
segs[segments].load_addr = 0;
segs[segments].len = (unsigned int)shdr[i].sh_size;
segs[segments].offset = doffset;
memcpy((unsigned long *)(output->data + doffset),
&header[shdr[i].sh_offset], shdr[i].sh_size);
doffset += segs[segments].len;
osize += segs[segments].len;
segments++;
}
}
for (i = 0; i < headers; i++) {
if (phdr[i].p_type != PT_LOAD)
continue;
if (phdr[i].p_memsz == 0)
continue;
if (phdr[i].p_filesz == 0) {
segs[segments].type = PAYLOAD_SEGMENT_BSS;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[segments].load_addr = phdr[i].p_paddr;
segs[segments].mem_len = phdr[i].p_memsz;
segs[segments].offset = doffset;
segments++;
continue;
}
if (phdr[i].p_flags & PF_X)
segs[segments].type = PAYLOAD_SEGMENT_CODE;
else
segs[segments].type = PAYLOAD_SEGMENT_DATA;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[segments].load_addr = phdr[i].p_paddr;
segs[segments].mem_len = phdr[i].p_memsz;
segs[segments].offset = doffset;
cbfstool: If compression fails, warn and use the uncompressed data. The LZMA compression algorithm, currently the only one available, will fail if you ask it to write more data to the output than you've given it space for. The code that calls into LZMA allocates an output buffer the same size as the input, so if compression increases the size of the output the call will fail. The caller(s) were written to assume that the call succeeded and check the returned length to see if the size would have increased, but that will never happen with LZMA. Rather than try to rework the LZMA library to dynamically resize the output buffer or try to guess what the maximal size the data could expand to is, this change makes the caller simply print a warning and disable compression if the call failed for some reason. This may lead to images that are larger than necessary if compression fails for some other reason and the user doesn't notice, but since compression errors were ignored entirely until very recently that will hopefully not be a problem in practice, and we should be guaranteed to at least produce a correct image. Original-Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Original-Signed-off-by: Gabe Black <gabeblack@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/187365 Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Original-Tested-by: Gabe Black <gabeblack@chromium.org> Original-Commit-Queue: Gabe Black <gabeblack@chromium.org> (cherry picked from commit b9f622a554d5fb9a9aff839c64e11acb27785f13) Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Reviewed-on: http://review.coreboot.org/6958 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-02-21 10:01:06 +01:00
/* If the compression failed or made the section is larger,
use the original stuff */
int len;
if (compress((char *)&header[phdr[i].p_offset],
cbfstool: If compression fails, warn and use the uncompressed data. The LZMA compression algorithm, currently the only one available, will fail if you ask it to write more data to the output than you've given it space for. The code that calls into LZMA allocates an output buffer the same size as the input, so if compression increases the size of the output the call will fail. The caller(s) were written to assume that the call succeeded and check the returned length to see if the size would have increased, but that will never happen with LZMA. Rather than try to rework the LZMA library to dynamically resize the output buffer or try to guess what the maximal size the data could expand to is, this change makes the caller simply print a warning and disable compression if the call failed for some reason. This may lead to images that are larger than necessary if compression fails for some other reason and the user doesn't notice, but since compression errors were ignored entirely until very recently that will hopefully not be a problem in practice, and we should be guaranteed to at least produce a correct image. Original-Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Original-Signed-off-by: Gabe Black <gabeblack@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/187365 Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Original-Tested-by: Gabe Black <gabeblack@chromium.org> Original-Commit-Queue: Gabe Black <gabeblack@chromium.org> (cherry picked from commit b9f622a554d5fb9a9aff839c64e11acb27785f13) Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Reviewed-on: http://review.coreboot.org/6958 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-02-21 10:01:06 +01:00
phdr[i].p_filesz, output->data + doffset, &len) ||
(unsigned int)len > phdr[i].p_filesz) {
WARN("Compression failed or would make the data bigger "
"- disabled.\n");
segs[segments].compression = 0;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[segments].len = phdr[i].p_filesz;
memcpy(output->data + doffset,
&header[phdr[i].p_offset], phdr[i].p_filesz);
cbfstool: If compression fails, warn and use the uncompressed data. The LZMA compression algorithm, currently the only one available, will fail if you ask it to write more data to the output than you've given it space for. The code that calls into LZMA allocates an output buffer the same size as the input, so if compression increases the size of the output the call will fail. The caller(s) were written to assume that the call succeeded and check the returned length to see if the size would have increased, but that will never happen with LZMA. Rather than try to rework the LZMA library to dynamically resize the output buffer or try to guess what the maximal size the data could expand to is, this change makes the caller simply print a warning and disable compression if the call failed for some reason. This may lead to images that are larger than necessary if compression fails for some other reason and the user doesn't notice, but since compression errors were ignored entirely until very recently that will hopefully not be a problem in practice, and we should be guaranteed to at least produce a correct image. Original-Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Original-Signed-off-by: Gabe Black <gabeblack@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/187365 Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Original-Tested-by: Gabe Black <gabeblack@chromium.org> Original-Commit-Queue: Gabe Black <gabeblack@chromium.org> (cherry picked from commit b9f622a554d5fb9a9aff839c64e11acb27785f13) Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Reviewed-on: http://review.coreboot.org/6958 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-02-21 10:01:06 +01:00
} else {
segs[segments].compression = algo;
segs[segments].len = len;
}
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
doffset += segs[segments].len;
osize += segs[segments].len;
segments++;
}
segs[segments].type = PAYLOAD_SEGMENT_ENTRY;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[segments++].load_addr = ehdr.e_entry;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
output->size = (segments * sizeof(*segs)) + osize;
xdr_segs(output, segs, segments);
out:
if (segs) free(segs);
if (shdr) free(shdr);
if (phdr) free(phdr);
return ret;
}
int parse_flat_binary_to_payload(const struct buffer *input,
struct buffer *output,
uint32_t loadaddress,
uint32_t entrypoint,
comp_algo algo)
{
comp_func_ptr compress;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
struct cbfs_payload_segment segs[2];
int doffset, len = 0;
compress = compression_function(algo);
if (!compress)
return -1;
DEBUG("start: parse_flat_binary_to_payload\n");
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
if (buffer_create(output, (sizeof(segs) + input->size),
input->name) != 0)
return -1;
memset(output->data, 0, output->size);
doffset = (2 * sizeof(*segs));
/* Prepare code segment */
segs[0].type = PAYLOAD_SEGMENT_CODE;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[0].load_addr = loadaddress;
segs[0].mem_len = input->size;
segs[0].offset = doffset;
cbfstool: If compression fails, warn and use the uncompressed data. The LZMA compression algorithm, currently the only one available, will fail if you ask it to write more data to the output than you've given it space for. The code that calls into LZMA allocates an output buffer the same size as the input, so if compression increases the size of the output the call will fail. The caller(s) were written to assume that the call succeeded and check the returned length to see if the size would have increased, but that will never happen with LZMA. Rather than try to rework the LZMA library to dynamically resize the output buffer or try to guess what the maximal size the data could expand to is, this change makes the caller simply print a warning and disable compression if the call failed for some reason. This may lead to images that are larger than necessary if compression fails for some other reason and the user doesn't notice, but since compression errors were ignored entirely until very recently that will hopefully not be a problem in practice, and we should be guaranteed to at least produce a correct image. Original-Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Original-Signed-off-by: Gabe Black <gabeblack@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/187365 Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Original-Tested-by: Gabe Black <gabeblack@chromium.org> Original-Commit-Queue: Gabe Black <gabeblack@chromium.org> (cherry picked from commit b9f622a554d5fb9a9aff839c64e11acb27785f13) Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Reviewed-on: http://review.coreboot.org/6958 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-02-21 10:01:06 +01:00
if (!compress(input->data, input->size, output->data + doffset, &len) &&
(unsigned int)len < input->size) {
segs[0].compression = algo;
segs[0].len = len;
} else {
WARN("Compression failed or would make the data bigger "
"- disabled.\n");
segs[0].compression = 0;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[0].len = input->size;
memcpy(output->data + doffset, input->data, input->size);
}
/* prepare entry point segment */
segs[1].type = PAYLOAD_SEGMENT_ENTRY;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[1].load_addr = entrypoint;
output->size = doffset + segs[0].len;
xdr_segs(output, segs, 2);
return 0;
}
int parse_fv_to_payload(const struct buffer *input,
struct buffer *output, comp_algo algo)
{
comp_func_ptr compress;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
struct cbfs_payload_segment segs[2];
int doffset, len = 0;
firmware_volume_header_t *fv;
ffs_file_header_t *fh;
common_section_header_t *cs;
dos_header_t *dh;
coff_header_t *ch;
int dh_offset;
uint32_t loadaddress = 0;
uint32_t entrypoint = 0;
compress = compression_function(algo);
if (!compress)
return -1;
DEBUG("start: parse_fv_to_payload\n");
fv = (firmware_volume_header_t *)input->data;
if (fv->signature != FV_SIGNATURE) {
INFO("Not a UEFI firmware volume.\n");
return -1;
}
fh = (ffs_file_header_t *)(input->data + fv->header_length);
while (fh->file_type == FILETYPE_PAD) {
unsigned long offset = (fh->size[2] << 16) | (fh->size[1] << 8) | fh->size[0];
ERROR("skipping %lu bytes of FV padding\n", offset);
cbfstool: Clean up in preparation for adding new files This enables more warnings on the cbfstool codebase and fixes the issues that surface as a result. A memory leak that used to occur when compressing files with lzma is also found and fixed. Finally, there are several fixes for the Makefile: - Its autodependencies used to be broken because the target for the .dependencies file was misnamed; this meant that Make didn't know how to rebuild the file, and so would silently skip the step of updating it before including it. - The ability to build to a custom output directory by defining the obj variable had bitrotted. - The default value of the obj variable was causing implicit rules not to apply when specifying a file as a target without providing a custom value for obj. - Add a distclean target for removing the .dependencies file. BUG=chromium:461875 TEST=Build an image with cbfstool both before and after. BRANCH=None Change-Id: I951919d63443f2b053c2e67c1ac9872abc0a43ca Signed-off-by: Sol Boucher <solb@chromium.org> Original-Commit-Id: 49293443b4e565ca48d284e9a66f80c9c213975d Original-Change-Id: Ia7350c2c3306905984cfa711d5fc4631f0b43d5b Original-Signed-off-by: Sol Boucher <solb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/257340 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-on: http://review.coreboot.org/9937 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-06 00:38:03 +01:00
fh = (ffs_file_header_t *)(((uintptr_t)fh) + offset);
}
if (fh->file_type != FILETYPE_SEC) {
ERROR("Not a usable UEFI firmware volume.\n");
INFO("First file in first FV not a SEC core.\n");
return -1;
}
cs = (common_section_header_t *)&fh[1];
while (cs->section_type == SECTION_RAW) {
unsigned long offset = (cs->size[2] << 16) | (cs->size[1] << 8) | cs->size[0];
ERROR("skipping %lu bytes of section padding\n", offset);
cbfstool: Clean up in preparation for adding new files This enables more warnings on the cbfstool codebase and fixes the issues that surface as a result. A memory leak that used to occur when compressing files with lzma is also found and fixed. Finally, there are several fixes for the Makefile: - Its autodependencies used to be broken because the target for the .dependencies file was misnamed; this meant that Make didn't know how to rebuild the file, and so would silently skip the step of updating it before including it. - The ability to build to a custom output directory by defining the obj variable had bitrotted. - The default value of the obj variable was causing implicit rules not to apply when specifying a file as a target without providing a custom value for obj. - Add a distclean target for removing the .dependencies file. BUG=chromium:461875 TEST=Build an image with cbfstool both before and after. BRANCH=None Change-Id: I951919d63443f2b053c2e67c1ac9872abc0a43ca Signed-off-by: Sol Boucher <solb@chromium.org> Original-Commit-Id: 49293443b4e565ca48d284e9a66f80c9c213975d Original-Change-Id: Ia7350c2c3306905984cfa711d5fc4631f0b43d5b Original-Signed-off-by: Sol Boucher <solb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/257340 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-on: http://review.coreboot.org/9937 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-06 00:38:03 +01:00
cs = (common_section_header_t *)(((uintptr_t)cs) + offset);
}
if (cs->section_type != SECTION_PE32) {
ERROR("Not a usable UEFI firmware volume.\n");
INFO("Section type not PE32.\n");
return -1;
}
dh = (dos_header_t *)&cs[1];
if (dh->signature != DOS_MAGIC) {
ERROR("Not a usable UEFI firmware volume.\n");
INFO("DOS header signature wrong.\n");
return -1;
}
dh_offset = (unsigned long)dh - (unsigned long)input->data;
DEBUG("dos header offset = %x\n", dh_offset);
cbfstool: Clean up in preparation for adding new files This enables more warnings on the cbfstool codebase and fixes the issues that surface as a result. A memory leak that used to occur when compressing files with lzma is also found and fixed. Finally, there are several fixes for the Makefile: - Its autodependencies used to be broken because the target for the .dependencies file was misnamed; this meant that Make didn't know how to rebuild the file, and so would silently skip the step of updating it before including it. - The ability to build to a custom output directory by defining the obj variable had bitrotted. - The default value of the obj variable was causing implicit rules not to apply when specifying a file as a target without providing a custom value for obj. - Add a distclean target for removing the .dependencies file. BUG=chromium:461875 TEST=Build an image with cbfstool both before and after. BRANCH=None Change-Id: I951919d63443f2b053c2e67c1ac9872abc0a43ca Signed-off-by: Sol Boucher <solb@chromium.org> Original-Commit-Id: 49293443b4e565ca48d284e9a66f80c9c213975d Original-Change-Id: Ia7350c2c3306905984cfa711d5fc4631f0b43d5b Original-Signed-off-by: Sol Boucher <solb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/257340 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-on: http://review.coreboot.org/9937 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2015-03-06 00:38:03 +01:00
ch = (coff_header_t *)(((uintptr_t)dh)+dh->e_lfanew);
if (ch->machine == MACHINE_TYPE_X86) {
pe_opt_header_32_t *ph;
ph = (pe_opt_header_32_t *)&ch[1];
if (ph->signature != PE_HDR_32_MAGIC) {
WARN("PE header signature incorrect.\n");
return -1;
}
DEBUG("image base %x\n", ph->image_addr);
DEBUG("entry point %x\n", ph->entry_point);
loadaddress = ph->image_addr - dh_offset;
entrypoint = ph->image_addr + ph->entry_point;
} else if (ch->machine == MACHINE_TYPE_X64) {
pe_opt_header_64_t *ph;
ph = (pe_opt_header_64_t *)&ch[1];
if (ph->signature != PE_HDR_64_MAGIC) {
WARN("PE header signature incorrect.\n");
return -1;
}
DEBUG("image base %lx\n", (unsigned long)ph->image_addr);
DEBUG("entry point %x\n", ph->entry_point);
loadaddress = ph->image_addr - dh_offset;
entrypoint = ph->image_addr + ph->entry_point;
} else {
ERROR("Machine type not x86 or x64.\n");
return -1;
}
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
if (buffer_create(output, (sizeof(segs) + input->size),
input->name) != 0)
return -1;
memset(output->data, 0, output->size);
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
doffset = (sizeof(segs));
/* Prepare code segment */
segs[0].type = PAYLOAD_SEGMENT_CODE;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[0].load_addr = loadaddress;
segs[0].mem_len = input->size;
segs[0].offset = doffset;
cbfstool: If compression fails, warn and use the uncompressed data. The LZMA compression algorithm, currently the only one available, will fail if you ask it to write more data to the output than you've given it space for. The code that calls into LZMA allocates an output buffer the same size as the input, so if compression increases the size of the output the call will fail. The caller(s) were written to assume that the call succeeded and check the returned length to see if the size would have increased, but that will never happen with LZMA. Rather than try to rework the LZMA library to dynamically resize the output buffer or try to guess what the maximal size the data could expand to is, this change makes the caller simply print a warning and disable compression if the call failed for some reason. This may lead to images that are larger than necessary if compression fails for some other reason and the user doesn't notice, but since compression errors were ignored entirely until very recently that will hopefully not be a problem in practice, and we should be guaranteed to at least produce a correct image. Original-Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Original-Signed-off-by: Gabe Black <gabeblack@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/187365 Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Original-Tested-by: Gabe Black <gabeblack@chromium.org> Original-Commit-Queue: Gabe Black <gabeblack@chromium.org> (cherry picked from commit b9f622a554d5fb9a9aff839c64e11acb27785f13) Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Change-Id: I5f59529c2d48e9c4c2e011018b40ec336c4fcca8 Reviewed-on: http://review.coreboot.org/6958 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2014-02-21 10:01:06 +01:00
if (!compress(input->data, input->size, output->data + doffset, &len) &&
(unsigned int)len < input->size) {
segs[0].compression = algo;
segs[0].len = len;
} else {
WARN("Compression failed or would make the data bigger "
"- disabled.\n");
segs[0].compression = 0;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[0].len = input->size;
memcpy(output->data + doffset, input->data, input->size);
}
/* prepare entry point segment */
segs[1].type = PAYLOAD_SEGMENT_ENTRY;
Add section header parsing and use it in the mk-payload step This completes the improvements to the ELF file parsing code. We can now parse section headers too, across all 4 combinations of word size and endianness. I had hoped to completely remove the use of htonl until I found it in cbfs_image.c. That's a battle for another day. There's now a handy macro to create magic numbers in host byte order. I'm using it for all the PAYLOAD_SEGMENT_* constants and maybe we can use it for the others too, but this is sensitive code and I'd rather change one thing at a time. To maximize the ease of use for users, elf parsing is accomplished with just one function: int elf_headers(const struct buffer *pinput, Elf64_Ehdr *ehdr, Elf64_Phdr **pphdr, Elf64_Shdr **pshdr) which requires the ehdr and pphdr pointers to be non-NULL, but allows the pshdr to be NULL. If pshdr is NULL, the code will not try to read in section headers. To satisfy our powerful scripts, I had to remove the ^M from an unrelated microcode file. BUG=None TEST=Build a peppy image (known to boot) with old and new versions and verify they are bit-for-bit the same. This was also fully tested across all chromebooks for building and booting and running chromeos. BRANCH=None Change-Id: I54dad887d922428b6175fdb6a9cdfadd8a6bb889 Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/181272 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: http://review.coreboot.org/5098 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
2013-12-30 22:16:18 +01:00
segs[1].load_addr = entrypoint;
output->size = doffset + segs[0].len;
xdr_segs(output, segs, 2);
return 0;
}