summaryrefslogtreecommitdiffstats
path: root/import
diff options
context:
space:
mode:
authorClaus Michael Olsen <cmolsen@us.ibm.com>2016-08-10 15:13:32 -0500
committerSachin Gupta <sgupta2m@in.ibm.com>2016-08-24 11:36:34 -0400
commitf98936ce13c5e2087d335f30cbf81e70776e15dd (patch)
treef61786811b6d430cd4e88f2b71426d5889161049 /import
parentbb68965f35de82a0bb6fc5680c6aab6b4b5b227b (diff)
downloadtalos-sbe-f98936ce13c5e2087d335f30cbf81e70776e15dd.tar.gz
talos-sbe-f98936ce13c5e2087d335f30cbf81e70776e15dd.zip
p9_xip_delete_section: Modified API
This API has been updated to remove any random section, not just the last section. Also, an update has been made to p9_xip_tool, which uses this API. Change-Id: I0acdcd24d860093322cf13abf98511032e5b3eb1 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28125 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Richard J. Knight <rjknight@us.ibm.com> Reviewed-by: Prachi Gupta <pragupta@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28130 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'import')
-rw-r--r--import/chips/p9/xip/p9_xip_image.c223
-rw-r--r--import/chips/p9/xip/p9_xip_image.h47
-rw-r--r--import/chips/p9/xip/p9_xip_tool.C14
3 files changed, 243 insertions, 41 deletions
diff --git a/import/chips/p9/xip/p9_xip_image.c b/import/chips/p9/xip/p9_xip_image.c
index 19474172..0f9ce1f7 100644
--- a/import/chips/p9/xip/p9_xip_image.c
+++ b/import/chips/p9/xip/p9_xip_image.c
@@ -51,7 +51,6 @@
#include <endian.h>
#include "p9_xip_image.h"
-
////////////////////////////////////////////////////////////////////////////
// Local Functions
////////////////////////////////////////////////////////////////////////////
@@ -101,7 +100,6 @@ XIP_STATIC P9_XIP_ERROR_STRINGS(p9_xip_error_strings);
(x); \
})
-
// Uncomment these if required for debugging, otherwise we get warnings from
// GCC as they are not otherwise used.
@@ -640,6 +638,53 @@ xipImage2Section(const void* i_image,
}
+// Delete the last, i.e., final, section of the image.
+
+XIP_STATIC int
+xipDeleteLastSection(void* io_image,
+ const int i_sectionId)
+{
+ int rc, final;
+ P9XipSection section;
+
+ do
+ {
+
+ xipSetSectionOffset(io_image, i_sectionId, 0);
+ xipSetSectionSize(io_image, i_sectionId, 0);
+
+
+ // For cleanliness we also remove any alignment padding that had been
+ // appended between the now-last section and the deleted section, then
+ // re-establish the final alignment. The assumption is that all images
+ // always have the correct final alignment, so there is no way this
+ // could overflow a designated buffer space since the image size is
+ // the same or has been reduced.
+
+ rc = xipFinalSection(io_image, &final);
+
+ if (rc)
+ {
+ break;
+ }
+
+ rc = p9_xip_get_section(io_image, final, &section);
+
+ if (rc)
+ {
+ break;
+ }
+
+ xipSetImageSize(io_image, section.iv_offset + section.iv_size);
+ xipFinalAlignment(io_image);
+
+ }
+ while (0);
+
+ return rc;
+}
+
+
/// Get the information required to search the TOC.
///
/// All return values are optional.
@@ -2477,62 +2522,79 @@ p9_xip_write_uint64(void* io_image,
int
-p9_xip_delete_section(void* io_image, const int i_sectionId)
+p9_xip_delete_section(void* io_image,
+ void* o_imageBuf,
+ const uint32_t i_imageBufSize,
+ const int i_sectionId)
{
int rc, final;
P9XipSection section;
+ size_t imageSize;
+ uint8_t bImageChanged = 0; // Tracks if io_image has been modified.
do
{
- rc = xipQuickCheck(io_image, 1);
- if (rc)
+ // Get image size. We'll need it a lot.
+
+ imageSize = xipImageSize(io_image);
+
+ // Parm check 1: imageBufSize
+ // - Must be >=imageSize for a valid imageBuf buffer
+
+ if (i_imageBufSize < imageSize && o_imageBuf != NULL)
{
+ rc = TRACE_ERRORX(P9_XIP_WOULD_OVERFLOW,
+ "xip_delete_section(): imageBufSize too small");
break;
}
- rc = p9_xip_get_section(io_image, i_sectionId, &section);
+ // Parm check 2: sectionId
+ // - It is illegal to remove the .header. It would kill the image.
- if (rc)
+ if (i_sectionId == P9_XIP_SECTION_HEADER)
{
+ rc = TRACE_ERRORX(P9_XIP_SECTION_ERROR,
+ "xip_delete_section(): It is illegal to remove .header");
break;
}
+ // Copy io_image to o_imageBuf if a valid imageBuf ptr is
+ // supplied, i.e., imageBuf!=NULL. We'll need a reference copy
+ // of any delected section to be re-appended after the section
+ // delete process is done.
+ if (o_imageBuf != NULL)
+ {
+ // We always return a copy of the original input image.
+ memcpy(o_imageBuf, io_image, imageSize);
+ }
- // Deleting an empty section is a NOP. Otherwise the section must be
- // the final section of the image. Update the sizes and re-establish
- // the final image alignment.
+ // Check the image
- if (section.iv_size == 0)
+ rc = xipQuickCheck(io_image, 1);
+
+ if (rc)
{
break;
}
- rc = xipFinalSection(io_image, &final);
+ // Deleting an empty section is a NOP. Otherwise the section must be
+ // the final section of the image. Update the sizes and re-establish
+ // the final image alignment.
+
+ rc = p9_xip_get_section(io_image, i_sectionId, &section);
if (rc)
{
break;
}
- if (final != i_sectionId)
+ if (section.iv_size == 0)
{
- rc = TRACE_ERRORX(P9_XIP_SECTION_ERROR,
- "Attempt to delete non-final section %d\n",
- i_sectionId);
break;
}
- xipSetSectionOffset(io_image, i_sectionId, 0);
- xipSetSectionSize(io_image, i_sectionId, 0);
-
-
- // For cleanliness we also remove any alignment padding that had been
- // appended between the now-last section and the deleted section, then
- // re-establish the final alignment. The assumption is that all images
- // always have the correct final alignment, so there is no way this
- // could overflow a designated buffer space since the image size is
- // the same or has been reduced.
+ // Determine last image section.
rc = xipFinalSection(io_image, &final);
@@ -2541,19 +2603,120 @@ p9_xip_delete_section(void* io_image, const int i_sectionId)
break;
}
- rc = p9_xip_get_section(io_image, final, &section);
+ // Now, delete necessary sections in order of highest section offset
+ // to the offset of the section, i_sectionId, to be removed.
- if (rc)
+ if (final == i_sectionId)
{
+ rc = xipDeleteLastSection(io_image, i_sectionId);
+
+ bImageChanged = 1;
+
break;
}
+ else
+ {
+ // Check for imageBuf ptr violation. If this fails, this is
+ // catastrophic since we don't have a reference copy of the input
+ // image (i.e, the memcpy of the image earlier wasn't executed.)
- xipSetImageSize(io_image, section.iv_offset + section.iv_size);
- xipFinalAlignment(io_image);
+ if (o_imageBuf == NULL)
+ {
+ rc = TRACE_ERRORX(P9_XIP_NULL_BUFFER,
+ "xip_delete_section(): Can't copy image into NULL buffer\n");
+ break;
+ }
+
+ // Delete sections, in order, that have offset addresses higher
+ // than i_sectionId and make a note of the order which is to
+ // be used when re-appending. Then delete i_sectionId.
+
+ uint8_t sectionOrder[P9_XIP_SECTIONS];
+ uint8_t orderIdx = 0;
+
+ do
+ {
+
+ rc = xipFinalSection(io_image, &final);
+
+ if (rc)
+ {
+ break;
+ }
+
+ // It is illegal to remove .header. It would kill the image.
+ if (final == P9_XIP_SECTION_HEADER)
+ {
+ rc = TRACE_ERRORX(P9_XIP_SECTION_ERROR,
+ "xip_delete_section(): Code bug: Attempt to remove .header");
+ break;
+ }
+
+ if (final != i_sectionId)
+ {
+ sectionOrder[orderIdx] = final;
+ orderIdx++;
+ }
+
+ rc = xipDeleteLastSection(io_image, final);
+
+ bImageChanged = 1;
+
+ if (rc)
+ {
+ break;
+ }
+
+ }
+ while (final != i_sectionId);
+
+ if (rc)
+ {
+ break;
+ }
+
+ // Reappend previously deleted sections in original order
+
+ do
+ {
+
+ orderIdx--;
+ rc = p9_xip_get_section(o_imageBuf, sectionOrder[orderIdx], &section);
+
+ if (rc)
+ {
+ break;
+ }
+
+ rc = p9_xip_append( io_image,
+ sectionOrder[orderIdx],
+ (void*)(((uint8_t*)o_imageBuf) + section.iv_offset),
+ (const uint32_t)section.iv_size,
+ (const uint32_t)imageSize,
+ NULL );
+
+ if (rc)
+ {
+ break;
+ }
+
+ }
+ while (orderIdx);
+
+ break;
+ }
}
while (0);
+ // Restore broken input image in case of rc!=0. But only do so if input
+ // image has changed.
+
+ if (rc && bImageChanged)
+ {
+ memcpy(io_image, o_imageBuf, imageSize);
+ }
+
return rc;
}
diff --git a/import/chips/p9/xip/p9_xip_image.h b/import/chips/p9/xip/p9_xip_image.h
index 92fb45ca..09bc1aa5 100644
--- a/import/chips/p9/xip/p9_xip_image.h
+++ b/import/chips/p9/xip/p9_xip_image.h
@@ -1035,23 +1035,38 @@ p9_xip_find(void* i_image,
-/// Delete a section from a P9-XIP image in host memory
+/// Delete any section, except .header, from a P9-XIP image in host memory,
+/// even in-between sections, i.e. non-final sections.
///
/// \param[in,out] io_image A pointer to a P9-XIP image in host memory. The
/// image is assumed to be consistent with the information contained in the
/// header regarding the presence of and sizes of all sections. The image is
-/// also required to have been normalized.
+/// also required to have been normalized. In case of failure in this
+/// funtion, the io_image will get restored to its input value.
+///
+/// \param[out] o_imageBuf A pointer to a pre-allocated buffer that MUST
+/// BE greater than or equal to the size of the \a io_image. The size of
+/// this buffer must be supplied in \a i_imageBufSize. If \a o_imageBuf
+/// is NULL, the supplied \a i_sectionId must be the final section in the
+/// image or this function will fail at deleting the section. On return
+/// from this function, o_imageBuf contains a copy of the initial input
+/// image \a io_image, but only if it's a valid buffer.
+///
+/// \param[in] i_imageBufSize The size of \a o_imageBuf buffer. It MUST
+/// BE greater than or equal to the size of \a io_image. However, if \a
+/// o_imageBuf is NULL, then this arg is ignored.
///
/// \param[in] i_sectionId Identifies the section to be deleted. See \ref
/// p9_xip_sections.
///
/// This API effectively deletes a section from a P9-XIP image held in host
-/// memory. Unless the requested section \a i_section is already empty, only
-/// the final (highest address offset) section of the image may be deleted.
-/// Deleting the final section of the image means that the section size is set
-/// to 0, and the size of the image recorded in the header is reduced by the
-/// section size. Any alignment padding of the now-last section is also
-/// removed.
+/// memory. Deleting a section of the image means that the section size is
+/// set to 0, and the size of the image recorded in the header is reduced by
+/// the section size. Any alignment padding of the in-between section is
+/// also handled, i.e. removed if final section and re-applied upon
+/// re-appending sections. In the special case where \a o_imageBuf is
+/// NULL, unless the requested \a i_sectionId is already empty, only the final
+/// section (highest address offset) of the image may be deleted.
///
/// \note This API does not check for or warn if other sections in the image
/// reference the deleted section.
@@ -1060,7 +1075,11 @@ p9_xip_find(void* i_image,
///
/// \retval non-0 See \ref p9_xip_image_errors
int
-p9_xip_delete_section(void* io_image, const int i_sectionId);
+p9_xip_delete_section(void* io_image,
+ void* o_imageBuf,
+ const uint32_t i_imageBufSize,
+ const int i_sectionId);
+
#ifndef PPC_HYP
@@ -1422,9 +1441,15 @@ p9_xip_decode_toc_dump(void* i_image, void* i_dump,
/// Error associated with the disassembler occured.
#define P9_XIP_DISASSEMBLER_ERROR 15
-/// hash collision creating the .fixed_toc section
+/// Hash collision creating the .fixed_toc section
#define P9_XIP_HASH_COLLISION 16
+/// Invalid buffer. It had a NULL ptr.
+#define P9_XIP_NULL_BUFFER 17
+
+/// Image has been broken and unable to restore original image.
+#define P9_XIP_CANT_RESTORE_IMAGE 18
+
/// Applications can expand this macro to declare an array of string forms of
/// the error codes if desired.
#define P9_XIP_ERROR_STRINGS(var) \
@@ -1446,6 +1471,8 @@ p9_xip_decode_toc_dump(void* i_image, void* i_dump,
"P9_XIP_WOULD_OVERFLOW", \
"P9_XIP_DISASSEMBLER_ERROR", \
"P9_XIP_HASH_COLLISION", \
+ "P9_XIP_NULL_BUFFER", \
+ "P9_XIP_CANT_RESTORE_IMAGE", \
}
/// Applications can use this macro to safely index the array of error
diff --git a/import/chips/p9/xip/p9_xip_tool.C b/import/chips/p9/xip/p9_xip_tool.C
index e35c4e8b..dd48e250 100644
--- a/import/chips/p9/xip/p9_xip_tool.C
+++ b/import/chips/p9/xip/p9_xip_tool.C
@@ -1454,6 +1454,7 @@ deleteSection(const char* i_imageFile, const int i_imageFd, void* io_image,
const char* section;
const char** argv;
void* newImage;
+ void* tempImage;
uint32_t size;
P9XipHeader header;
@@ -1491,6 +1492,17 @@ deleteSection(const char* i_imageFile, const int i_imageFd, void* io_image,
exit(1);
}
+ // Create a temporary place holder for image
+
+ tempImage = malloc(size);
+
+ if (tempImage == 0)
+ {
+ fprintf(stderr, "Can't malloc() a buffer for the temporary image\n");
+ exit(1);
+ }
+
+
p9_xip_translate_header(&header, (P9XipHeader*)io_image);
// Delete the sections in argument order
@@ -1512,7 +1524,7 @@ deleteSection(const char* i_imageFile, const int i_imageFd, void* io_image,
// Delete the section
- rc = p9_xip_delete_section(newImage, sectionId);
+ rc = p9_xip_delete_section(newImage, tempImage, size, sectionId);
if (rc)
{
OpenPOWER on IntegriCloud