1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "courgette/ensemble.h"
7 #include "base/basictypes.h"
8 #include "base/string_number_conversions.h"
10 #include "courgette/image_info.h"
11 #include "courgette/region.h"
12 #include "courgette/streams.h"
13 #include "courgette/simple_delta.h"
17 Element::Element(ExecutableType kind
,
21 : kind_(kind
), ensemble_(ensemble
), region_(region
), info_(info
) {
28 std::string
Element::Name() const {
29 return ensemble_
->name() + "("
30 + base::IntToString(kind()) + ","
31 + base::Uint64ToString(offset_in_ensemble()) + ","
32 + base::Uint64ToString(region().length()) + ")";
35 // Scans the Ensemble's region, sniffing out Elements. We assume that the
36 // elements do not overlap.
37 Status
Ensemble::FindEmbeddedElements() {
39 size_t length
= region_
.length();
40 const uint8
* start
= region_
.start();
43 while (position
< length
) {
44 ExecutableType type
= DetectExecutableType(start
+ position
,
48 // TODO(dgarrett) This switch can go away totally after two things.
50 // Make ImageInfo generic for all executable types.
51 // Find a generic way to handle length detection for executables.
53 // When this switch is gone, that's one less piece of code that is
54 // executable type aware.
58 // No Element found at current position.
63 // The Info is only created to detect the length of the executable
64 courgette::PEInfo
* info(new courgette::PEInfo());
65 info
->Init(start
+ position
, length
- position
);
66 if (!info
->ParseHeader()) {
71 Region
region(start
+ position
, info
->length());
73 Element
* element
= new Element(type
, this, region
, info
);
74 owned_elements_
.push_back(element
);
75 elements_
.push_back(element
);
76 position
+= region
.length();
84 Ensemble::~Ensemble() {
85 for (size_t i
= 0; i
< owned_elements_
.size(); ++i
)
86 delete owned_elements_
[i
];