Index: courgette/ensemble.cc |
diff --git a/courgette/ensemble.cc b/courgette/ensemble.cc |
index 69e07a7a52567970bc4da53466d18a0e160da718..a2bea8f38b7d6086ed8ace733927e27739a5fbdf 100644 |
--- a/courgette/ensemble.cc |
+++ b/courgette/ensemble.cc |
@@ -1,4 +1,4 @@ |
-// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
@@ -14,8 +14,15 @@ |
namespace courgette { |
-Element::Element(Kind kind, Ensemble* ensemble, const Region& region) |
- : kind_(kind), ensemble_(ensemble), region_(region) { |
+Element::Element(ExecutableType kind, |
+ Ensemble* ensemble, |
+ const Region& region, |
+ PEInfo* info) |
+ : kind_(kind), ensemble_(ensemble), region_(region), info_(info) { |
+} |
+ |
+Element::~Element() { |
+ delete info_; |
} |
std::string Element::Name() const { |
@@ -25,71 +32,51 @@ std::string Element::Name() const { |
+ base::Uint64ToString(region().length()) + ")"; |
} |
-// A subclass of Element that has a PEInfo. |
-class ElementWinPE : public Element { |
- public: |
- ElementWinPE(Kind kind, Ensemble* ensemble, const Region& region, |
- PEInfo* info) |
- : Element(kind, ensemble, region), |
- pe_info_(info) { |
- } |
- |
- virtual PEInfo* GetPEInfo() const { return pe_info_; } |
- |
- protected: |
- ~ElementWinPE() { delete pe_info_; } |
- |
- private: |
- PEInfo* pe_info_; // Owned by |this|. |
-}; |
- |
// Scans the Ensemble's region, sniffing out Elements. We assume that the |
// elements do not overlap. |
Status Ensemble::FindEmbeddedElements() { |
+ |
size_t length = region_.length(); |
const uint8* start = region_.start(); |
size_t position = 0; |
while (position < length) { |
- // Quick test; Windows executables begin with 'MZ'. |
- if (start[position] == 'M' && |
- position + 1 < length && start[position + 1] == 'Z') { |
- courgette::PEInfo *info = new courgette::PEInfo(); |
- info->Init(start + position, length - position); |
- if (info->ParseHeader()) { |
- Region region(start + position, info->length()); |
- |
- if (info->has_text_section()) { |
- if (info->is_32bit()) { |
- Element* element = new ElementWinPE(Element::WIN32_X86_WITH_CODE, |
- this, region, info); |
- owned_elements_.push_back(element); |
- elements_.push_back(element); |
- position += region.length(); |
- continue; |
- } |
- // TODO(sra): Extend to 64-bit executables. |
+ ExecutableType type = DetectExecutableType(start + position, |
+ length - position); |
+ |
+ // |
+ // TODO(dgarrett) This switch can go away totally after two things. |
+ // |
+ // Make ImageInfo generic for all executable types. |
+ // Find a generic way to handle length detection for executables. |
+ // |
+ // When this switch is gone, that's one less piece of code that is |
+ // executable type aware. |
+ // |
+ switch (type) { |
+ case UNKNOWN: { |
+ // No Element found at current position. |
+ ++position; |
+ break; |
+ } |
+ case WIN32_X86: { |
+ // The Info is only created to detect the length of the executable |
+ courgette::PEInfo* info(new courgette::PEInfo()); |
+ info->Init(start + position, length - position); |
+ if (!info->ParseHeader()) { |
+ delete info; |
+ position++; |
+ break; |
} |
+ Region region(start + position, info->length()); |
- // If we had a clever transformation for resource-only executables we |
- // should identify the suitable elements here: |
- if (!info->has_text_section() && false) { |
- Element* element = new ElementWinPE(Element::WIN32_NOCODE, |
- this, region, info); |
- owned_elements_.push_back(element); |
- elements_.push_back(element); |
- position += region.length(); |
- continue; |
- } |
+ Element* element = new Element(type, this, region, info); |
+ owned_elements_.push_back(element); |
+ elements_.push_back(element); |
+ position += region.length(); |
+ break; |
} |
- delete info; |
} |
- |
- // This is where to add new formats, e.g. Linux executables, Dalvik |
- // executables etc. |
- |
- // No Element found at current position. |
- ++position; |
} |
return C_OK; |
} |