summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@chromium.org>2014-04-01 02:17:20 -0400
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-04-01 23:21:47 +0000
commit7d9288a0745aa50dbcb0bb692241f0eee679254b (patch)
tree82eb157a8b0c1194363d30a8d746f1b68edafda6
parent515197db4f204bf942b4d4f57bd994cc2e7e9c0c (diff)
downloadrootdev-7d9288a0745aa50dbcb0bb692241f0eee679254b.tar.gz
fix building w/ABIs that have broken stat structures
If the system's stat buffer is broken and doesn't declare st_dev as a dev_t, we hit a build failure when we try to pass it into a func that expects a dev_t. Add some checks to handle this case. It produces the same code on sane ABIs, so other than ugliness, it should be fine. BUG=chromium:358419 TEST=`emerge-link rootdev` produces same code TEST=`emerge-daisy rootdev` produces same code TEST=`emerge-mipsel-o32-generic rootdev` now works Change-Id: I956436e0c40318c8f2ac61b2e202ec739132c245 Reviewed-on: https://chromium-review.googlesource.com/192550 Reviewed-by: Mike Frysinger <vapier@chromium.org> Commit-Queue: Mike Frysinger <vapier@chromium.org> Tested-by: Mike Frysinger <vapier@chromium.org>
-rw-r--r--rootdev.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/rootdev.c b/rootdev.c
index 76c931c..ea88b39 100644
--- a/rootdev.c
+++ b/rootdev.c
@@ -404,16 +404,28 @@ int rootdev_wrapper(char *path, size_t size,
int rootdev(char *path, size_t size, bool full, bool strip) {
struct stat root_statbuf;
+ dev_t _root_dev, *root_dev = &_root_dev;
/* Yields the containing dev_t in st_dev. */
if (stat("/", &root_statbuf) != 0)
return -1;
+ /* Some ABIs (like mips o32) are broken and the st_dev field isn't actually
+ * a dev_t. In that case, pass a pointer to a local dev_t who we took care
+ * of truncating the value into. On sane arches, gcc can optimize this to
+ * the same code, so should only be a penalty when the ABI is broken. */
+ if (sizeof(root_statbuf.st_dev) == sizeof(*root_dev)) {
+ /* Cast is OK since we verified size here. */
+ root_dev = (dev_t *)&root_statbuf.st_dev;
+ } else {
+ *root_dev = root_statbuf.st_dev;
+ }
+
return rootdev_wrapper(path,
size,
full,
strip,
- &root_statbuf.st_dev,
+ root_dev,
NULL, /* default /sys dir */
NULL); /* default /dev dir */
}